From d9ff9c20ee0112afdc436b1ed2baaf7ef252a46b Mon Sep 17 00:00:00 2001 From: seamymckenna Date: Fri, 16 Dec 2016 15:05:53 +0000 Subject: [PATCH] (maint) add puppetise laptop (#36) * updated install script to create custom fact * updated site to use new qa modules * adding new qa modules * update to source xcode file correctly * updated $path for running xcode script * added gemset and bundler * adding floaty gem * adding software module * update to use seamymckenna fork of bitbar * update to use root to config def rvm gemset * update to not use root to config def rvm gemset --- tools/laptop_puppetisation/README.md | 8 +- tools/laptop_puppetisation/install_agent.rb | 24 +- .../modules/gnupg/CHANGELOG | 49 + .../modules/gnupg/CONTRIBUTING.md | 216 +++ .../modules/gnupg/Gemfile | 33 + .../modules/gnupg/LICENSE | 201 ++ .../modules/gnupg/README.md | 225 +++ .../modules/gnupg/Rakefile | 16 + .../modules/gnupg/checksums.json | 45 + .../modules/gnupg/files/broken.public.key | 30 + .../modules/gnupg/files/random.key | 28 + .../modules/gnupg/files/random.private.key | 58 + .../modules/gnupg/files/random.public.key | 30 + .../modules/gnupg/lib/facter/gnupg_command.rb | 18 + .../gnupg/lib/facter/gnupg_installed.rb | 18 + .../lib/puppet/provider/gnupg_key/gnupg.rb | 166 ++ .../gnupg/lib/puppet/type/gnupg_key.rb | 153 ++ .../modules/gnupg/manifests/init.pp | 29 + .../modules/gnupg/manifests/install.pp | 9 + .../modules/gnupg/manifests/params.pp | 30 + .../modules/gnupg/metadata.json | 67 + .../gnupg/spec/acceptance/class_spec.rb | 28 + .../spec/acceptance/gnupg_key_install_spec.rb | 388 ++++ .../acceptance/nodesets/centos-59-x64.yml | 10 + .../acceptance/nodesets/centos-64-x64-pe.yml | 12 + .../acceptance/nodesets/centos-64-x64.yml | 11 + .../acceptance/nodesets/centos-65-x64.yml | 10 + .../acceptance/nodesets/debian-607-x64.yml | 11 + .../acceptance/nodesets/debian-70rc1-x64.yml | 11 + .../acceptance/nodesets/debian-73-i386.yml | 11 + .../acceptance/nodesets/debian-73-x64.yml | 11 + .../spec/acceptance/nodesets/default.yml | 11 + .../nodesets/ubuntu-server-10044-x64.yml | 10 + .../nodesets/ubuntu-server-12042-x64.yml | 10 + .../nodesets/ubuntu-server-1310-x64.yml | 11 + .../nodesets/ubuntu-server-1404-x64.yml | 11 + .../gnupg/spec/classes/gnupg_init_spec.rb | 39 + .../modules/gnupg/spec/spec.opts | 6 + .../modules/gnupg/spec/spec_helper.rb | 3 + .../gnupg/spec/spec_helper_acceptance.rb | 48 + .../modules/gnupg/spec/spec_helper_system.rb | 66 + .../spec/system/gnupg_key_install_spec.rb | 152 ++ .../modules/gnupg/spec/system/install_spec.rb | 16 + .../spec/unit/puppet/type/gnupg_key_spec.rb | 127 ++ .../modules/gnupg/tests/gnupg_key.pp | 40 + .../modules/gnupg/tests/init.pp | 1 + .../modules/homebrew/CHANGELOG.md | 61 + .../modules/homebrew/Gemfile | 9 + .../modules/homebrew/Gemfile-1.9.3 | 10 + .../modules/homebrew/README.md | 150 ++ .../modules/homebrew/checksums.json | 25 + .../modules/homebrew/circle.yml | 18 + .../modules/homebrew/lib/facter/has_brew.rb | 12 + .../homebrew/lib/facter/has_compiler.rb | 21 + .../lib/puppet/provider/package/brew.rb | 84 + .../lib/puppet/provider/package/brewcask.rb | 82 + .../lib/puppet/provider/package/brewcommon.rb | 94 + .../lib/puppet/provider/package/homebrew.rb | 89 + .../lib/puppet/provider/package/tap.rb | 64 + .../modules/homebrew/manifests/compiler.pp | 16 + .../modules/homebrew/manifests/init.pp | 30 + .../modules/homebrew/manifests/install.pp | 23 + .../modules/homebrew/metadata.json | 25 + .../modules/homebrew/test.sh | 67 + .../modules/homebrew/tests/init.pp | 4 + .../modules/homebrew/tests/install_options.pp | 7 + .../modules/homebrew/tests/packages.pp | 19 + .../modules/homebrew/tests/tap.pp | 13 + .../modules/homebrew/tests/tap_priority.pp | 11 + .../modules/homebrew/tests/token.pp | 5 + .../modules/qahomebrew/manifests/init.pp | 53 + .../modules/qapackages/manifests/init.pp | 12 + .../modules/qarubyecosystem/manifests/init.pp | 40 + .../qavmpoolerbitbar/manifests/init.pp | 37 + .../modules/qaxcode/examples/init.pp | 1 + .../qaxcode/files/install_xcode_cli_tools.sh | 11 + .../modules/qaxcode/manifests/init.pp | 25 + .../laptop_puppetisation/modules/rvm/Gemfile | 17 + .../laptop_puppetisation/modules/rvm/LICENSE | 24 + .../modules/rvm/README.markdown | 282 +++ .../laptop_puppetisation/modules/rvm/Rakefile | 31 + .../modules/rvm/checksums.json | 65 + .../modules/rvm/lib/facter/rvm_installed.rb | 7 + .../modules/rvm/lib/facter/rvm_version.rb | 7 + .../lib/puppet/provider/rvm_alias/alias.rb | 46 + .../rvm/lib/puppet/provider/rvm_gem/gem.rb | 144 ++ .../lib/puppet/provider/rvm_gemset/gemset.rb | 57 + .../rvm_system_ruby/rvm_system_ruby.rb | 66 + .../puppet/provider/rvm_wrapper/wrapper.rb | 37 + .../modules/rvm/lib/puppet/type/rvm_alias.rb | 20 + .../modules/rvm/lib/puppet/type/rvm_gem.rb | 157 ++ .../modules/rvm/lib/puppet/type/rvm_gemset.rb | 33 + .../rvm/lib/puppet/type/rvm_system_ruby.rb | 35 + .../rvm/lib/puppet/type/rvm_wrapper.rb | 20 + .../modules/rvm/manifests/dependencies.pp | 9 + .../rvm/manifests/dependencies/centos.pp | 25 + .../rvm/manifests/dependencies/oraclelinux.pp | 7 + .../rvm/manifests/dependencies/ubuntu.pp | 9 + .../modules/rvm/manifests/gnupg_key.pp | 15 + .../modules/rvm/manifests/gpg.pp | 7 + .../modules/rvm/manifests/group.pp | 7 + .../modules/rvm/manifests/init.pp | 43 + .../modules/rvm/manifests/params.pp | 29 + .../modules/rvm/manifests/passenger/apache.pp | 105 + .../rvm/manifests/passenger/dependencies.pp | 9 + .../passenger/dependencies/centos.pp | 17 + .../passenger/dependencies/oraclelinux.pp | 4 + .../passenger/dependencies/ubuntu.pp | 4 + .../modules/rvm/manifests/passenger/gem.pp | 11 + .../modules/rvm/manifests/rvmrc.pp | 19 + .../modules/rvm/manifests/system.pp | 74 + .../modules/rvm/manifests/system_user.pp | 40 + .../modules/rvm/metadata.json | 121 ++ .../nodesets/centos-65-x64-docker.yml | 23 + .../acceptance/nodesets/centos-65-x64.yml | 14 + .../nodesets/debian-7-x64-docker.yml | 22 + .../spec/acceptance/nodesets/debian-7-x64.yml | 14 + .../acceptance/nodesets/debian-73-x64.yml | 14 + .../rvm/spec/acceptance/nodesets/default.yml | 23 + .../ubuntu-server-1404-x64-docker.yml | 22 + .../nodesets/ubuntu-server-1404-x64.yml | 14 + .../rvm/spec/acceptance/rvm_system_spec.rb | 419 ++++ .../rvm/spec/classes/dependencies_spec.rb | 68 + .../rvm/spec/classes/gnupg_key_spec.rb | 9 + .../modules/rvm/spec/classes/gpg_spec.rb | 29 + .../modules/rvm/spec/classes/init_spec.rb | 54 + .../modules/rvm/spec/classes/rvmrc_spec.rb | 19 + .../modules/rvm/spec/classes/system_spec.rb | 56 + .../rvm/spec/defines/rvm_alias_spec.rb | 11 + .../modules/rvm/spec/defines/rvm_gem_spec.rb | 13 + .../rvm/spec/defines/rvm_gemset_spec.rb | 15 + .../rvm/spec/defines/rvm_system_ruby_spec.rb | 10 + .../rvm/spec/defines/rvm_wrapper_spec.rb | 15 + .../rvm/spec/defines/system_user_spec.rb | 34 + .../modules/rvm/spec/fixtures/hiera.yaml | 11 + .../modules/rvm/spec/spec_helper.rb | 33 + .../rvm/spec/spec_helper_acceptance.rb | 52 + .../modules/rvm/templates/rvmrc.erb | 12 + .../modules/rvm/tests/init.pp | 7 + .../modules/software/.fixtures.yml | 6 + .../modules/software/.gitignore | 42 + .../modules/software/.rubocop.yml | 48 + .../modules/software/.ruby-gemset | 1 + .../modules/software/.travis.yml | 19 + .../modules/software/CHANGELOG | 59 + .../modules/software/Gemfile | 59 + .../modules/software/LICENSE | 674 +++++++ .../modules/software/README.md | 166 ++ .../modules/software/Rakefile | 59 + .../lib/puppet/provider/package/apm.rb | 114 ++ .../puppet/provider/package/appcompressed.rb | 100 + .../provider/package/prefpanecompressed.rb | 100 + .../modules/software/manifests/browsers.pp | 28 + .../software/manifests/browsers/chrome.pp | 63 + .../software/manifests/browsers/firefox.pp | 41 + .../modules/software/manifests/database.pp | 36 + .../manifests/database/mysqlworkbench.pp | 43 + .../manifests/database/pgcommander.pp | 33 + .../software/manifests/database/sequelpro.pp | 30 + .../modules/software/manifests/drivers.pp | 20 + .../manifests/drivers/lanier_mpc5503.pp | 53 + .../modules/software/manifests/editors.pp | 36 + .../software/manifests/editors/atom.pp | 97 + .../software/manifests/editors/textmate.pp | 31 + .../manifests/editors/textwrangler.pp | 30 + .../modules/software/manifests/editors/vim.pp | 28 + .../software/manifests/entertainment.pp | 23 + .../software/manifests/entertainment/vlc.pp | 41 + .../modules/software/manifests/idesdk.pp | 26 + .../manifests/idesdk/android_studio.pp | 36 + .../manifests/idesdk/android_tools.pp | 29 + .../modules/software/manifests/init.pp | 23 + .../modules/software/manifests/params.pp | 164 ++ .../modules/software/manifests/prefpanes.pp | 28 + .../software/manifests/prefpanes/hosts.pp | 30 + .../manifests/prefpanes/launchrocket.pp | 30 + .../modules/software/manifests/social.pp | 20 + .../software/manifests/social/skype.pp | 55 + .../modules/software/manifests/storage.pp | 35 + .../software/manifests/storage/drive.pp | 56 + .../software/manifests/storage/fetch.pp | 30 + .../software/manifests/storage/filezilla.pp | 42 + .../modules/software/manifests/utilities.pp | 52 + .../software/manifests/utilities/alfred.pp | 72 + .../manifests/utilities/controlplane.pp | 45 + .../software/manifests/utilities/iterm.pp | 45 + .../software/manifests/utilities/onyx.pp | 47 + .../manifests/utilities/openconnect.pp | 23 + .../software/manifests/utilities/synaptic.pp | 22 + .../modules/software/manifests/vcsscm.pp | 22 + .../modules/software/manifests/vcsscm/git.pp | 35 + .../software/manifests/vcsscm/sourcetree.pp | 36 + .../software/manifests/virtualization.pp | 22 + .../manifests/virtualization/vagrant.pp | 29 + .../manifests/virtualization/virtualbox.pp | 65 + .../modules/software/manifests/webstack.pp | 26 + .../software/manifests/webstack/anvil.pp | 28 + .../modules/software/metadata.json | 44 + .../classes/software_browsers_chrome_spec.rb | 15 + .../classes/software_editors_atom_spec.rb | 15 + ...software_virtualization_virtualbox_spec.rb | 15 + .../modules/software/spec/spec.opts | 6 + .../modules/software/spec/spec_helper.rb | 8 + .../modules/stdlib/CHANGELOG.md | 736 +++++++ .../modules/stdlib/CONTRIBUTING.md | 218 +++ .../modules/stdlib/Gemfile | 85 + .../modules/stdlib/LICENSE | 202 ++ .../modules/stdlib/NOTICE | 23 + .../modules/stdlib/README.markdown | 1720 +++++++++++++++++ .../modules/stdlib/README_DEVELOPER.markdown | 35 + .../modules/stdlib/README_SPECS.markdown | 7 + .../modules/stdlib/RELEASE_PROCESS.markdown | 24 + .../modules/stdlib/Rakefile | 38 + .../modules/stdlib/checksums.json | 497 +++++ .../modules/stdlib/examples/file_line.pp | 9 + .../stdlib/examples/has_interface_with.pp | 9 + .../modules/stdlib/examples/has_ip_address.pp | 3 + .../modules/stdlib/examples/has_ip_network.pp | 3 + .../modules/stdlib/examples/init.pp | 1 + .../modules/stdlib/lib/facter/facter_dot_d.rb | 202 ++ .../stdlib/lib/facter/package_provider.rb | 21 + .../modules/stdlib/lib/facter/pe_version.rb | 58 + .../stdlib/lib/facter/puppet_settings.rb | 35 + .../modules/stdlib/lib/facter/root_home.rb | 45 + .../stdlib/lib/facter/service_provider.rb | 17 + .../stdlib/lib/facter/util/puppet_settings.rb | 21 + .../lib/puppet/functions/deprecation.rb | 29 + .../stdlib/lib/puppet/functions/is_a.rb | 32 + .../lib/puppet/functions/is_absolute_path.rb | 15 + .../stdlib/lib/puppet/functions/is_array.rb | 15 + .../stdlib/lib/puppet/functions/is_bool.rb | 15 + .../stdlib/lib/puppet/functions/is_float.rb | 15 + .../lib/puppet/functions/is_ip_address.rb | 15 + .../lib/puppet/functions/is_ipv4_address.rb | 15 + .../lib/puppet/functions/is_ipv6_address.rb | 15 + .../stdlib/lib/puppet/functions/is_numeric.rb | 15 + .../stdlib/lib/puppet/functions/is_string.rb | 15 + .../stdlib/lib/puppet/functions/type_of.rb | 19 + .../functions/validate_absolute_path.rb | 15 + .../lib/puppet/functions/validate_array.rb | 15 + .../lib/puppet/functions/validate_bool.rb | 15 + .../lib/puppet/functions/validate_hash.rb | 15 + .../lib/puppet/functions/validate_integer.rb | 15 + .../puppet/functions/validate_ip_address.rb | 15 + .../puppet/functions/validate_ipv4_address.rb | 15 + .../puppet/functions/validate_ipv6_address.rb | 15 + .../lib/puppet/functions/validate_legacy.rb | 62 + .../lib/puppet/functions/validate_numeric.rb | 15 + .../lib/puppet/functions/validate_re.rb | 15 + .../lib/puppet/functions/validate_slength.rb | 15 + .../lib/puppet/functions/validate_string.rb | 15 + .../stdlib/lib/puppet/parser/functions/abs.rb | 36 + .../lib/puppet/parser/functions/any2array.rb | 33 + .../lib/puppet/parser/functions/any2bool.rb | 55 + .../puppet/parser/functions/assert_private.rb | 29 + .../lib/puppet/parser/functions/base64.rb | 68 + .../lib/puppet/parser/functions/basename.rb | 34 + .../lib/puppet/parser/functions/bool2num.rb | 26 + .../lib/puppet/parser/functions/bool2str.rb | 45 + .../lib/puppet/parser/functions/camelcase.rb | 33 + .../lib/puppet/parser/functions/capitalize.rb | 33 + .../lib/puppet/parser/functions/ceiling.rb | 25 + .../lib/puppet/parser/functions/chomp.rb | 34 + .../lib/puppet/parser/functions/chop.rb | 36 + .../lib/puppet/parser/functions/clamp.rb | 30 + .../lib/puppet/parser/functions/concat.rb | 41 + .../puppet/parser/functions/convert_base.rb | 35 + .../lib/puppet/parser/functions/count.rb | 22 + .../lib/puppet/parser/functions/deep_merge.rb | 44 + .../parser/functions/defined_with_params.rb | 38 + .../lib/puppet/parser/functions/delete.rb | 45 + .../lib/puppet/parser/functions/delete_at.rb | 49 + .../puppet/parser/functions/delete_regex.rb | 45 + .../parser/functions/delete_undef_values.rb | 34 + .../puppet/parser/functions/delete_values.rb | 26 + .../puppet/parser/functions/deprecation.rb | 17 + .../lib/puppet/parser/functions/difference.rb | 36 + .../stdlib/lib/puppet/parser/functions/dig.rb | 16 + .../lib/puppet/parser/functions/dig44.rb | 73 + .../lib/puppet/parser/functions/dirname.rb | 21 + .../lib/puppet/parser/functions/dos2unix.rb | 15 + .../lib/puppet/parser/functions/downcase.rb | 32 + .../lib/puppet/parser/functions/empty.rb | 31 + .../puppet/parser/functions/enclose_ipv6.rb | 45 + .../parser/functions/ensure_packages.rb | 46 + .../parser/functions/ensure_resource.rb | 46 + .../parser/functions/ensure_resources.rb | 54 + .../lib/puppet/parser/functions/flatten.rb | 33 + .../lib/puppet/parser/functions/floor.rb | 25 + .../parser/functions/fqdn_rand_string.rb | 34 + .../puppet/parser/functions/fqdn_rotate.rb | 63 + .../parser/functions/get_module_path.rb | 17 + .../lib/puppet/parser/functions/getparam.rb | 35 + .../lib/puppet/parser/functions/getvar.rb | 35 + .../lib/puppet/parser/functions/grep.rb | 33 + .../parser/functions/has_interface_with.rb | 71 + .../puppet/parser/functions/has_ip_address.rb | 25 + .../puppet/parser/functions/has_ip_network.rb | 25 + .../lib/puppet/parser/functions/has_key.rb | 28 + .../lib/puppet/parser/functions/hash.rb | 41 + .../puppet/parser/functions/intersection.rb | 34 + .../parser/functions/is_absolute_path.rb | 50 + .../lib/puppet/parser/functions/is_array.rb | 22 + .../lib/puppet/parser/functions/is_bool.rb | 22 + .../puppet/parser/functions/is_domain_name.rb | 54 + .../parser/functions/is_email_address.rb | 21 + .../lib/puppet/parser/functions/is_float.rb | 32 + .../parser/functions/is_function_available.rb | 26 + .../lib/puppet/parser/functions/is_hash.rb | 22 + .../lib/puppet/parser/functions/is_integer.rb | 47 + .../puppet/parser/functions/is_ip_address.rb | 34 + .../parser/functions/is_ipv4_address.rb | 30 + .../parser/functions/is_ipv6_address.rb | 30 + .../puppet/parser/functions/is_mac_address.rb | 27 + .../lib/puppet/parser/functions/is_numeric.rb | 75 + .../lib/puppet/parser/functions/is_string.rb | 29 + .../lib/puppet/parser/functions/join.rb | 41 + .../parser/functions/join_keys_to_values.rb | 56 + .../lib/puppet/parser/functions/keys.rb | 26 + .../parser/functions/load_module_metadata.rb | 24 + .../lib/puppet/parser/functions/loadjson.rb | 34 + .../lib/puppet/parser/functions/loadyaml.rb | 34 + .../lib/puppet/parser/functions/lstrip.rb | 32 + .../stdlib/lib/puppet/parser/functions/max.rb | 21 + .../lib/puppet/parser/functions/member.rb | 62 + .../lib/puppet/parser/functions/merge.rb | 34 + .../stdlib/lib/puppet/parser/functions/min.rb | 21 + .../lib/puppet/parser/functions/num2bool.rb | 43 + .../lib/puppet/parser/functions/parsejson.rb | 29 + .../lib/puppet/parser/functions/parseyaml.rb | 33 + .../lib/puppet/parser/functions/pick.rb | 29 + .../puppet/parser/functions/pick_default.rb | 35 + .../lib/puppet/parser/functions/prefix.rb | 52 + .../lib/puppet/parser/functions/private.rb | 17 + .../lib/puppet/parser/functions/pw_hash.rb | 56 + .../lib/puppet/parser/functions/range.rb | 87 + .../puppet/parser/functions/regexpescape.rb | 31 + .../lib/puppet/parser/functions/reject.rb | 31 + .../lib/puppet/parser/functions/reverse.rb | 27 + .../lib/puppet/parser/functions/rstrip.rb | 31 + .../puppet/parser/functions/seeded_rand.rb | 22 + .../puppet/parser/functions/shell_escape.rb | 30 + .../lib/puppet/parser/functions/shell_join.rb | 31 + .../puppet/parser/functions/shell_split.rb | 26 + .../lib/puppet/parser/functions/shuffle.rb | 45 + .../lib/puppet/parser/functions/size.rb | 46 + .../lib/puppet/parser/functions/sort.rb | 27 + .../lib/puppet/parser/functions/squeeze.rb | 36 + .../lib/puppet/parser/functions/str2bool.rb | 46 + .../parser/functions/str2saltedsha512.rb | 32 + .../lib/puppet/parser/functions/strftime.rb | 107 + .../lib/puppet/parser/functions/strip.rb | 38 + .../lib/puppet/parser/functions/suffix.rb | 53 + .../lib/puppet/parser/functions/swapcase.rb | 38 + .../lib/puppet/parser/functions/time.rb | 50 + .../lib/puppet/parser/functions/to_bytes.rb | 31 + .../puppet/parser/functions/try_get_value.rb | 53 + .../lib/puppet/parser/functions/type.rb | 19 + .../lib/puppet/parser/functions/type3x.rb | 51 + .../lib/puppet/parser/functions/union.rb | 29 + .../lib/puppet/parser/functions/unique.rb | 50 + .../lib/puppet/parser/functions/unix2dos.rb | 15 + .../lib/puppet/parser/functions/upcase.rb | 45 + .../lib/puppet/parser/functions/uriescape.rb | 34 + .../functions/validate_absolute_path.rb | 54 + .../puppet/parser/functions/validate_array.rb | 35 + .../parser/functions/validate_augeas.rb | 83 + .../puppet/parser/functions/validate_bool.rb | 37 + .../puppet/parser/functions/validate_cmd.rb | 63 + .../functions/validate_email_address.rb | 31 + .../puppet/parser/functions/validate_hash.rb | 35 + .../parser/functions/validate_integer.rb | 134 ++ .../parser/functions/validate_ip_address.rb | 52 + .../parser/functions/validate_ipv4_address.rb | 50 + .../parser/functions/validate_ipv6_address.rb | 51 + .../parser/functions/validate_numeric.rb | 96 + .../puppet/parser/functions/validate_re.rb | 50 + .../parser/functions/validate_slength.rb | 71 + .../parser/functions/validate_string.rb | 41 + .../functions/validate_x509_rsa_key_pair.rb | 47 + .../lib/puppet/parser/functions/values.rb | 39 + .../lib/puppet/parser/functions/values_at.rb | 99 + .../stdlib/lib/puppet/parser/functions/zip.rb | 39 + .../lib/puppet/provider/file_line/ruby.rb | 132 ++ .../modules/stdlib/lib/puppet/type/anchor.rb | 46 + .../stdlib/lib/puppet/type/file_line.rb | 125 ++ .../modules/stdlib/manifests/init.pp | 18 + .../modules/stdlib/manifests/stages.pp | 43 + .../modules/stdlib/metadata.json | 112 ++ .../stdlib/spec/acceptance/abs_spec.rb | 30 + .../stdlib/spec/acceptance/anchor_spec.rb | 26 + .../stdlib/spec/acceptance/any2array_spec.rb | 49 + .../stdlib/spec/acceptance/base64_spec.rb | 18 + .../stdlib/spec/acceptance/bool2num_spec.rb | 34 + .../stdlib/spec/acceptance/build_csv.rb | 83 + .../stdlib/spec/acceptance/capitalize_spec.rb | 33 + .../stdlib/spec/acceptance/ceiling_spec.rb | 39 + .../stdlib/spec/acceptance/chomp_spec.rb | 21 + .../stdlib/spec/acceptance/chop_spec.rb | 45 + .../stdlib/spec/acceptance/clamp_spec.rb | 40 + .../stdlib/spec/acceptance/concat_spec.rb | 54 + .../stdlib/spec/acceptance/count_spec.rb | 30 + .../stdlib/spec/acceptance/deep_merge_spec.rb | 20 + .../acceptance/defined_with_params_spec.rb | 22 + .../stdlib/spec/acceptance/delete_at_spec.rb | 19 + .../stdlib/spec/acceptance/delete_spec.rb | 19 + .../acceptance/delete_undef_values_spec.rb | 19 + .../spec/acceptance/delete_values_spec.rb | 25 + .../spec/acceptance/deprecation_spec.rb | 102 + .../stdlib/spec/acceptance/difference_spec.rb | 26 + .../stdlib/spec/acceptance/dirname_spec.rb | 42 + .../stdlib/spec/acceptance/downcase_spec.rb | 39 + .../stdlib/spec/acceptance/empty_spec.rb | 53 + .../spec/acceptance/ensure_resource_spec.rb | 30 + .../stdlib/spec/acceptance/flatten_spec.rb | 39 + .../stdlib/spec/acceptance/floor_spec.rb | 39 + .../spec/acceptance/fqdn_rand_string_spec.rb | 66 + .../spec/acceptance/fqdn_rotate_spec.rb | 64 + .../spec/acceptance/get_module_path_spec.rb | 27 + .../stdlib/spec/acceptance/getparam_spec.rb | 24 + .../stdlib/spec/acceptance/getvar_spec.rb | 26 + .../stdlib/spec/acceptance/grep_spec.rb | 26 + .../acceptance/has_interface_with_spec.rb | 54 + .../spec/acceptance/has_ip_address_spec.rb | 33 + .../spec/acceptance/has_ip_network_spec.rb | 33 + .../stdlib/spec/acceptance/has_key_spec.rb | 41 + .../stdlib/spec/acceptance/hash_spec.rb | 26 + .../spec/acceptance/intersection_spec.rb | 27 + .../stdlib/spec/acceptance/is_a_spec.rb | 30 + .../stdlib/spec/acceptance/is_array_spec.rb | 67 + .../stdlib/spec/acceptance/is_bool_spec.rb | 81 + .../spec/acceptance/is_domain_name_spec.rb | 83 + .../stdlib/spec/acceptance/is_float_spec.rb | 86 + .../acceptance/is_function_available_spec.rb | 58 + .../stdlib/spec/acceptance/is_hash_spec.rb | 63 + .../stdlib/spec/acceptance/is_integer_spec.rb | 95 + .../spec/acceptance/is_ip_address_spec.rb | 80 + .../spec/acceptance/is_ipv4_address_spec.rb | 52 + .../spec/acceptance/is_ipv6_address_spec.rb | 66 + .../spec/acceptance/is_mac_address_spec.rb | 38 + .../stdlib/spec/acceptance/is_numeric_spec.rb | 95 + .../stdlib/spec/acceptance/is_string_spec.rb | 113 ++ .../acceptance/join_keys_to_values_spec.rb | 24 + .../stdlib/spec/acceptance/join_spec.rb | 26 + .../stdlib/spec/acceptance/keys_spec.rb | 23 + .../stdlib/spec/acceptance/loadjson_spec.rb | 52 + .../stdlib/spec/acceptance/loadyaml_spec.rb | 56 + .../stdlib/spec/acceptance/lstrip_spec.rb | 34 + .../stdlib/spec/acceptance/max_spec.rb | 20 + .../stdlib/spec/acceptance/member_spec.rb | 54 + .../stdlib/spec/acceptance/merge_spec.rb | 23 + .../stdlib/spec/acceptance/min_spec.rb | 20 + .../spec/acceptance/nodesets/centos-7-x64.yml | 10 + .../spec/acceptance/nodesets/debian-8-x64.yml | 10 + .../spec/acceptance/nodesets/default.yml | 10 + .../acceptance/nodesets/docker/centos-7.yml | 12 + .../acceptance/nodesets/docker/debian-8.yml | 11 + .../nodesets/docker/ubuntu-14.04.yml | 12 + .../stdlib/spec/acceptance/num2bool_spec.rb | 76 + .../stdlib/spec/acceptance/parsejson_spec.rb | 55 + .../stdlib/spec/acceptance/parseyaml_spec.rb | 58 + .../spec/acceptance/pick_default_spec.rb | 54 + .../stdlib/spec/acceptance/pick_spec.rb | 44 + .../stdlib/spec/acceptance/prefix_spec.rb | 42 + .../stdlib/spec/acceptance/pw_hash_spec.rb | 34 + .../stdlib/spec/acceptance/range_spec.rb | 36 + .../stdlib/spec/acceptance/reject_spec.rb | 42 + .../stdlib/spec/acceptance/reverse_spec.rb | 23 + .../stdlib/spec/acceptance/rstrip_spec.rb | 34 + .../stdlib/spec/acceptance/shuffle_spec.rb | 34 + .../stdlib/spec/acceptance/size_spec.rb | 55 + .../stdlib/spec/acceptance/sort_spec.rb | 34 + .../stdlib/spec/acceptance/squeeze_spec.rb | 47 + .../stdlib/spec/acceptance/str2bool_spec.rb | 31 + .../spec/acceptance/str2saltedsha512_spec.rb | 22 + .../stdlib/spec/acceptance/strftime_spec.rb | 22 + .../stdlib/spec/acceptance/strip_spec.rb | 34 + .../stdlib/spec/acceptance/suffix_spec.rb | 42 + .../stdlib/spec/acceptance/swapcase_spec.rb | 22 + .../stdlib/spec/acceptance/time_spec.rb | 36 + .../stdlib/spec/acceptance/to_bytes_spec.rb | 27 + .../spec/acceptance/try_get_value_spec.rb | 47 + .../stdlib/spec/acceptance/type_spec.rb | 37 + .../stdlib/spec/acceptance/union_spec.rb | 25 + .../stdlib/spec/acceptance/unique_spec.rb | 33 + .../spec/acceptance/unsupported_spec.rb | 11 + .../stdlib/spec/acceptance/upcase_spec.rb | 33 + .../stdlib/spec/acceptance/uriescape_spec.rb | 23 + .../acceptance/validate_absolute_path_spec.rb | 31 + .../spec/acceptance/validate_array_spec.rb | 37 + .../spec/acceptance/validate_augeas_spec.rb | 63 + .../spec/acceptance/validate_bool_spec.rb | 37 + .../spec/acceptance/validate_cmd_spec.rb | 52 + .../spec/acceptance/validate_hash_spec.rb | 37 + .../acceptance/validate_ipv4_address_spec.rb | 31 + .../acceptance/validate_ipv6_address_spec.rb | 31 + .../spec/acceptance/validate_re_spec.rb | 47 + .../spec/acceptance/validate_slength_spec.rb | 72 + .../spec/acceptance/validate_string_spec.rb | 43 + .../stdlib/spec/acceptance/values_at_spec.rb | 73 + .../stdlib/spec/acceptance/values_spec.rb | 35 + .../stdlib/spec/acceptance/zip_spec.rb | 86 + .../stdlib/spec/aliases/absolute_path_spec.rb | 62 + .../stdlib/spec/aliases/absolutepath_spec.rb | 49 + .../modules/stdlib/spec/aliases/array_spec.rb | 34 + .../modules/stdlib/spec/aliases/bool_spec.rb | 32 + .../modules/stdlib/spec/aliases/float_spec.rb | 28 + .../stdlib/spec/aliases/httpsurl_spec.rb | 40 + .../stdlib/spec/aliases/httpurl_spec.rb | 43 + .../stdlib/spec/aliases/integer_spec.rb | 28 + .../modules/stdlib/spec/aliases/ip_address.rb | 34 + .../modules/stdlib/spec/aliases/ipv4_spec.rb | 22 + .../modules/stdlib/spec/aliases/ipv6_spec.rb | 30 + .../stdlib/spec/aliases/numeric_spec.rb | 32 + .../stdlib/spec/aliases/string_spec.rb | 32 + .../stdlib/spec/aliases/unixpath_spec.rb | 41 + .../stdlib/spec/aliases/windowspath_spec.rb | 44 + .../stdlib/spec/fixtures/dscacheutil/root | 8 + .../modules/stdlib/spec/fixtures/lsuser/root | 2 + .../fixtures/test/manifests/absolute_path.pp | 6 + .../fixtures/test/manifests/absolutepath.pp | 6 + .../spec/fixtures/test/manifests/array.pp | 8 + .../spec/fixtures/test/manifests/bool.pp | 8 + .../spec/fixtures/test/manifests/float.pp | 8 + .../spec/fixtures/test/manifests/httpsurl.pp | 6 + .../spec/fixtures/test/manifests/httpurl.pp | 6 + .../spec/fixtures/test/manifests/integer.pp | 8 + .../fixtures/test/manifests/ip_address.pp | 6 + .../spec/fixtures/test/manifests/ipv4.pp | 6 + .../spec/fixtures/test/manifests/ipv6.pp | 6 + .../spec/fixtures/test/manifests/numeric.pp | 8 + .../spec/fixtures/test/manifests/string.pp | 8 + .../spec/fixtures/test/manifests/unixpath.pp | 6 + .../fixtures/test/manifests/windowspath.pp | 6 + .../modules/stdlib/spec/functions/abs_spec.rb | 30 + .../stdlib/spec/functions/any2array_spec.rb | 15 + .../stdlib/spec/functions/any2bool_spec.rb | 42 + .../spec/functions/assert_private_spec.rb | 41 + .../stdlib/spec/functions/base64_spec.rb | 37 + .../stdlib/spec/functions/basename_spec.rb | 14 + .../stdlib/spec/functions/bool2num_spec.rb | 14 + .../stdlib/spec/functions/bool2str_spec.rb | 17 + .../stdlib/spec/functions/camelcase_spec.rb | 17 + .../stdlib/spec/functions/capitalize_spec.rb | 15 + .../stdlib/spec/functions/ceiling_spec.rb | 13 + .../stdlib/spec/functions/chomp_spec.rb | 20 + .../stdlib/spec/functions/chop_spec.rb | 20 + .../stdlib/spec/functions/clamp_spec.rb | 16 + .../stdlib/spec/functions/concat_spec.rb | 25 + .../spec/functions/convert_base_spec.rb | 24 + .../stdlib/spec/functions/count_spec.rb | 18 + .../stdlib/spec/functions/deep_merge_spec.rb | 55 + .../functions/defined_with_params_spec.rb | 35 + .../stdlib/spec/functions/delete_at_spec.rb | 28 + .../spec/functions/delete_regex_spec.rb | 54 + .../stdlib/spec/functions/delete_spec.rb | 70 + .../functions/delete_undef_values_spec.rb | 56 + .../spec/functions/delete_values_spec.rb | 37 + .../stdlib/spec/functions/deprecation_spec.rb | 60 + .../stdlib/spec/functions/difference_spec.rb | 21 + .../stdlib/spec/functions/dig44_spec.rb | 105 + .../modules/stdlib/spec/functions/dig_spec.rb | 13 + .../stdlib/spec/functions/dirname_spec.rb | 13 + .../stdlib/spec/functions/dos2unix_spec.rb | 40 + .../stdlib/spec/functions/downcase_spec.rb | 15 + .../stdlib/spec/functions/empty_spec.rb | 22 + .../spec/functions/ensure_packages_spec.rb | 36 + .../spec/functions/ensure_resource_spec.rb | 93 + .../stdlib/spec/functions/flatten_spec.rb | 14 + .../stdlib/spec/functions/floor_spec.rb | 12 + .../spec/functions/fqdn_rand_string_spec.rb | 65 + .../stdlib/spec/functions/fqdn_rotate_spec.rb | 75 + .../spec/functions/get_module_path_spec.rb | 48 + .../stdlib/spec/functions/getparam_spec.rb | 27 + .../stdlib/spec/functions/getvar_spec.rb | 23 + .../stdlib/spec/functions/grep_spec.rb | 19 + .../spec/functions/has_interface_with_spec.rb | 38 + .../spec/functions/has_ip_address_spec.rb | 22 + .../spec/functions/has_ip_network_spec.rb | 22 + .../stdlib/spec/functions/has_key_spec.rb | 15 + .../stdlib/spec/functions/hash_spec.rb | 14 + .../spec/functions/intersection_spec.rb | 21 + .../stdlib/spec/functions/is_a_spec.rb | 25 + .../stdlib/spec/functions/is_array_spec.rb | 36 + .../stdlib/spec/functions/is_bool_spec.rb | 33 + .../spec/functions/is_domain_name_spec.rb | 43 + .../spec/functions/is_email_address_spec.rb | 14 + .../stdlib/spec/functions/is_float_spec.rb | 42 + .../spec/functions/is_function_available.rb | 9 + .../stdlib/spec/functions/is_hash_spec.rb | 11 + .../stdlib/spec/functions/is_integer_spec.rb | 45 + .../spec/functions/is_ip_address_spec.rb | 40 + .../spec/functions/is_ipv4_address_spec.rb | 32 + .../spec/functions/is_ipv6_address_spec.rb | 30 + .../spec/functions/is_mac_address_spec.rb | 24 + .../stdlib/spec/functions/is_numeric_spec.rb | 48 + .../stdlib/spec/functions/is_string_spec.rb | 47 + .../functions/join_keys_to_values_spec.rb | 23 + .../stdlib/spec/functions/join_spec.rb | 19 + .../stdlib/spec/functions/keys_spec.rb | 19 + .../functions/load_module_metadata_spec.rb | 38 + .../stdlib/spec/functions/loadjson_spec.rb | 49 + .../stdlib/spec/functions/loadyaml_spec.rb | 34 + .../stdlib/spec/functions/lstrip_spec.rb | 34 + .../modules/stdlib/spec/functions/max_spec.rb | 21 + .../stdlib/spec/functions/member_spec.rb | 21 + .../stdlib/spec/functions/merge_spec.rb | 25 + .../modules/stdlib/spec/functions/min_spec.rb | 21 + .../stdlib/spec/functions/num2bool_spec.rb | 22 + .../stdlib/spec/functions/parsejson_spec.rb | 64 + .../stdlib/spec/functions/parseyaml_spec.rb | 81 + .../spec/functions/pick_default_spec.rb | 24 + .../stdlib/spec/functions/pick_spec.rb | 12 + .../stdlib/spec/functions/prefix_spec.rb | 28 + .../stdlib/spec/functions/private_spec.rb | 56 + .../stdlib/spec/functions/pw_hash_spec.rb | 69 + .../stdlib/spec/functions/range_spec.rb | 118 ++ .../spec/functions/regexpescape_spec.rb | 36 + .../stdlib/spec/functions/reject_spec.rb | 19 + .../stdlib/spec/functions/reverse_spec.rb | 31 + .../stdlib/spec/functions/rstrip_spec.rb | 34 + .../stdlib/spec/functions/seeded_rand_spec.rb | 53 + .../spec/functions/shell_escape_spec.rb | 22 + .../stdlib/spec/functions/shell_join_spec.rb | 23 + .../stdlib/spec/functions/shell_split_spec.rb | 24 + .../stdlib/spec/functions/shuffle_spec.rb | 33 + .../stdlib/spec/functions/size_spec.rb | 35 + .../stdlib/spec/functions/sort_spec.rb | 24 + .../stdlib/spec/functions/squeeze_spec.rb | 44 + .../stdlib/spec/functions/str2bool_spec.rb | 23 + .../spec/functions/str2saltedsha512_spec.rb | 17 + .../stdlib/spec/functions/strftime_spec.rb | 26 + .../stdlib/spec/functions/strip_spec.rb | 34 + .../stdlib/spec/functions/suffix_spec.rb | 38 + .../stdlib/spec/functions/swapcase_spec.rb | 40 + .../stdlib/spec/functions/time_spec.rb | 21 + .../stdlib/spec/functions/to_bytes_spec.rb | 72 + .../spec/functions/try_get_value_spec.rb | 100 + .../stdlib/spec/functions/type3x_spec.rb | 41 + .../stdlib/spec/functions/type_of_spec.rb | 25 + .../stdlib/spec/functions/type_spec.rb | 42 + .../stdlib/spec/functions/union_spec.rb | 24 + .../stdlib/spec/functions/unique_spec.rb | 27 + .../stdlib/spec/functions/unix2dos_spec.rb | 40 + .../stdlib/spec/functions/upcase_spec.rb | 26 + .../stdlib/spec/functions/uriescape_spec.rb | 36 + .../functions/validate_absolute_path_spec.rb | 73 + .../spec/functions/validate_array_spec.rb | 37 + .../spec/functions/validate_augeas_spec.rb | 75 + .../spec/functions/validate_bool_spec.rb | 36 + .../spec/functions/validate_cmd_spec.rb | 35 + .../functions/validate_email_address_spec.rb | 23 + .../spec/functions/validate_hash_spec.rb | 38 + .../spec/functions/validate_integer_spec.rb | 101 + .../functions/validate_ip_address_spec.rb | 65 + .../functions/validate_ipv4_address_spec.rb | 41 + .../functions/validate_ipv6_address_spec.rb | 50 + .../spec/functions/validate_legacy_spec.rb | 68 + .../spec/functions/validate_numeric_spec.rb | 100 + .../stdlib/spec/functions/validate_re_spec.rb | 56 + .../spec/functions/validate_slength_spec.rb | 72 + .../spec/functions/validate_string_spec.rb | 33 + .../validate_x509_rsa_key_pair_spec.rb | 180 ++ .../stdlib/spec/functions/values_at_spec.rb | 49 + .../stdlib/spec/functions/values_spec.rb | 19 + .../modules/stdlib/spec/functions/zip_spec.rb | 15 + .../monkey_patches/alias_should_to_must.rb | 9 + .../spec/monkey_patches/publicize_methods.rb | 11 + .../modules/stdlib/spec/spec_helper.rb | 8 + .../stdlib/spec/spec_helper_acceptance.rb | 70 + .../modules/stdlib/spec/spec_helper_local.rb | 31 + .../stdlib/spec/support/shared_data.rb | 38 + .../spec/unit/facter/facter_dot_d_spec.rb | 32 + .../spec/unit/facter/package_provider_spec.rb | 44 + .../spec/unit/facter/pe_version_spec.rb | 88 + .../stdlib/spec/unit/facter/root_home_spec.rb | 65 + .../spec/unit/facter/service_provider_spec.rb | 37 + .../unit/facter/util/puppet_settings_spec.rb | 37 + .../parser/functions/enclose_ipv6_spec.rb | 69 + .../parser/functions/is_absolute_path_spec.rb | 86 + .../puppet/provider/file_line/ruby_spec.rb | 447 +++++ .../spec/unit/puppet/type/anchor_spec.rb | 11 + .../spec/unit/puppet/type/file_line_spec.rb | 76 + .../modules/stdlib/types/absolutepath.pp | 2 + .../stdlib/types/compat/absolute_path.pp | 7 + .../modules/stdlib/types/compat/array.pp | 2 + .../modules/stdlib/types/compat/bool.pp | 2 + .../modules/stdlib/types/compat/float.pp | 19 + .../modules/stdlib/types/compat/integer.pp | 23 + .../modules/stdlib/types/compat/ip_address.pp | 1 + .../modules/stdlib/types/compat/ipv4.pp | 2 + .../modules/stdlib/types/compat/ipv6.pp | 1 + .../modules/stdlib/types/compat/numeric.pp | 23 + .../modules/stdlib/types/compat/re.pp | 3 + .../modules/stdlib/types/compat/string.pp | 2 + .../modules/stdlib/types/httpsurl.pp | 1 + .../modules/stdlib/types/httpurl.pp | 1 + .../modules/stdlib/types/unixpath.pp | 2 + .../modules/stdlib/types/windowspath.pp | 1 + .../modules/vcsrepo/CHANGELOG.md | 159 ++ .../modules/vcsrepo/CONTRIBUTING.md | 218 +++ .../modules/vcsrepo/Gemfile | 48 + .../modules/vcsrepo/LICENSE | 339 ++++ .../modules/vcsrepo/NOTICE | 20 + .../modules/vcsrepo/README.markdown | 758 ++++++++ .../modules/vcsrepo/Rakefile | 38 + .../modules/vcsrepo/checksums.json | 156 ++ .../modules/vcsrepo/examples/bzr/branch.pp | 6 + .../modules/vcsrepo/examples/bzr/init_repo.pp | 4 + .../modules/vcsrepo/examples/cvs/local.pp | 11 + .../modules/vcsrepo/examples/cvs/remote.pp | 5 + .../modules/vcsrepo/examples/git/bare_init.pp | 4 + .../modules/vcsrepo/examples/git/clone.pp | 5 + .../git/shallow-clone-with-just-one-commit.pp | 7 + .../vcsrepo/examples/git/working_copy_init.pp | 4 + .../modules/vcsrepo/examples/hg/clone.pp | 6 + .../vcsrepo/examples/hg/clone_basic_auth.pp | 7 + .../modules/vcsrepo/examples/hg/init_repo.pp | 4 + .../vcsrepo/examples/p4/create_client.pp | 4 + .../vcsrepo/examples/p4/delete_client.pp | 4 + .../vcsrepo/examples/p4/latest_client.pp | 5 + .../vcsrepo/examples/p4/sync_client.pp | 6 + .../modules/vcsrepo/examples/svn/checkout.pp | 5 + .../modules/vcsrepo/examples/svn/server.pp | 4 + .../vcsrepo/lib/puppet/provider/vcsrepo.rb | 42 + .../lib/puppet/provider/vcsrepo/bzr.rb | 93 + .../lib/puppet/provider/vcsrepo/cvs.rb | 135 ++ .../lib/puppet/provider/vcsrepo/dummy.rb | 12 + .../lib/puppet/provider/vcsrepo/git.rb | 480 +++++ .../vcsrepo/lib/puppet/provider/vcsrepo/hg.rb | 130 ++ .../vcsrepo/lib/puppet/provider/vcsrepo/p4.rb | 278 +++ .../lib/puppet/provider/vcsrepo/svn.rb | 139 ++ .../vcsrepo/lib/puppet/type/vcsrepo.rb | 248 +++ .../modules/vcsrepo/metadata.json | 79 + .../basic_auth/basic_auth_checkout_http.rb | 69 + .../basic_auth/basic_auth_checkout_https.rb | 77 + .../negative/basic_auth_checkout_git.rb | 53 + .../branch_checkout/branch_checkout_file.rb | 48 + .../branch_checkout_file_path.rb | 48 + .../branch_checkout/branch_checkout_git.rb | 53 + .../branch_checkout/branch_checkout_http.rb | 61 + .../branch_checkout/branch_checkout_https.rb | 68 + .../branch_checkout/branch_checkout_scp.rb | 59 + .../branch_checkout/branch_checkout_ssh.rb | 59 + .../negative/branch_checkout_not_exists.rb | 46 + .../acceptance/beaker/git/clone/clone_file.rb | 46 + .../beaker/git/clone/clone_file_path.rb | 46 + .../acceptance/beaker/git/clone/clone_git.rb | 51 + .../acceptance/beaker/git/clone/clone_http.rb | 59 + .../beaker/git/clone/clone_https.rb | 66 + ..._over_different_exiting_repo_with_force.rb | 49 + .../clone/clone_repo_with_excludes_in_repo.rb | 46 + .../clone_repo_with_excludes_not_in_repo.rb | 46 + .../acceptance/beaker/git/clone/clone_scp.rb | 57 + .../acceptance/beaker/git/clone/clone_ssh.rb | 57 + .../clone_over_different_exiting_repo.rb | 47 + .../negative/clone_repo_with_exec_excludes.rb | 45 + .../git/compression/compression_0_checkout.rb | 43 + .../git/compression/compression_1_checkout.rb | 43 + .../git/compression/compression_2_checkout.rb | 43 + .../git/compression/compression_3_checkout.rb | 43 + .../git/compression/compression_4_checkout.rb | 43 + .../git/compression/compression_5_checkout.rb | 43 + .../git/compression/compression_6_checkout.rb | 43 + .../negative/compression_7_checkout.rb | 43 + .../negative/compression_alpha_checkout.rb | 43 + .../negative/compression_eval_checkout.rb | 43 + .../negative/compression_exec_checkout.rb | 43 + .../negative/compression_negative_checkout.rb | 43 + .../create_bare_repo_that_already_exists.rb | 40 + .../create/create_repo_that_already_exists.rb | 42 + .../create_bare_repo_specifying_revision.rb | 38 + .../git/group_checkout/group_checkout_file.rb | 53 + .../group_checkout_file_path.rb | 53 + .../git/group_checkout/group_checkout_git.rb | 58 + .../git/group_checkout/group_checkout_http.rb | 66 + .../group_checkout/group_checkout_https.rb | 73 + .../git/group_checkout/group_checkout_scp.rb | 64 + .../git/group_checkout/group_checkout_ssh.rb | 64 + .../group_checkout_file_non_existent_group.rb | 51 + .../negative/revision_checkout_not_exists.rb | 46 + .../revision_checkout_file.rb | 53 + .../revision_checkout_file_path.rb | 53 + .../revision_checkout_git.rb | 58 + .../revision_checkout_http.rb | 66 + .../revision_checkout_https.rb | 74 + .../revision_checkout_scp.rb | 64 + .../revision_checkout_ssh.rb | 64 + .../negative/shallow_clone_exec_depth.rb | 43 + .../negative/shallow_clone_file_path.rb | 44 + .../negative/shallow_clone_http.rb | 55 + .../negative/shallow_clone_negative_depth.rb | 43 + .../negative/shallow_clone_overflow_depth.rb | 45 + .../git/shallow_clone/shallow_clone_file.rb | 47 + .../git/shallow_clone/shallow_clone_git.rb | 52 + .../git/shallow_clone/shallow_clone_https.rb | 68 + .../git/shallow_clone/shallow_clone_scp.rb | 58 + .../git/shallow_clone/shallow_clone_ssh.rb | 58 + .../shallow_clone/shallow_clone_zero_depth.rb | 43 + .../negative/tag_checkout_not_exists.rb | 47 + .../git/tag_checkout/tag_checkout_file.rb | 48 + .../tag_checkout/tag_checkout_file_path.rb | 48 + .../git/tag_checkout/tag_checkout_git.rb | 59 + .../git/tag_checkout/tag_checkout_http.rb | 67 + .../git/tag_checkout/tag_checkout_https.rb | 74 + .../git/tag_checkout/tag_checkout_scp.rb | 65 + .../git/tag_checkout/tag_checkout_ssh.rb | 65 + .../user_checkout_file_non_existent_user.rb | 51 + .../git/user_checkout/user_checkout_file.rb | 53 + .../user_checkout/user_checkout_file_path.rb | 53 + .../git/user_checkout/user_checkout_git.rb | 58 + .../git/user_checkout/user_checkout_http.rb | 66 + .../git/user_checkout/user_checkout_https.rb | 73 + .../git/user_checkout/user_checkout_scp.rb | 64 + .../git/user_checkout/user_checkout_ssh.rb | 64 + .../vcsrepo/spec/acceptance/beaker_helper.rb | 51 + .../spec/acceptance/clone_repo_spec.rb | 534 +++++ .../spec/acceptance/create_repo_spec.rb | 89 + .../spec/acceptance/files/create_git_repo.sh | 39 + .../vcsrepo/spec/acceptance/files/server.crt | 13 + .../vcsrepo/spec/acceptance/files/server.key | 15 + .../spec/acceptance/modules_1596_spec.rb | 72 + .../spec/acceptance/modules_1800_spec.rb | 41 + .../spec/acceptance/modules_2326_spec.rb | 69 + .../spec/acceptance/modules_660_spec.rb | 89 + .../spec/acceptance/modules_753_spec.rb | 68 + .../spec/acceptance/nodesets/centos-7-x64.yml | 10 + .../spec/acceptance/nodesets/debian-8-x64.yml | 10 + .../spec/acceptance/nodesets/default.yml | 10 + .../acceptance/nodesets/docker/centos-7.yml | 12 + .../acceptance/nodesets/docker/debian-8.yml | 11 + .../nodesets/docker/ubuntu-14.04.yml | 12 + .../spec/acceptance/remove_repo_spec.rb | 30 + .../spec/acceptance/remove_repo_spec_noop.rb | 31 + .../spec/fixtures/bzr_version_info.txt | 5 + .../vcsrepo/spec/fixtures/git_branch_a.txt | 14 + .../spec/fixtures/git_branch_feature_bar.txt | 14 + .../vcsrepo/spec/fixtures/git_branch_none.txt | 15 + .../vcsrepo/spec/fixtures/hg_parents.txt | 6 + .../modules/vcsrepo/spec/fixtures/hg_tags.txt | 18 + .../vcsrepo/spec/fixtures/svn_info.txt | 10 + .../modules/vcsrepo/spec/spec.opts | 6 + .../modules/vcsrepo/spec/spec_helper.rb | 8 + .../vcsrepo/spec/spec_helper_acceptance.rb | 46 + .../modules/vcsrepo/spec/spec_helper_local.rb | 7 + .../spec/support/filesystem_helpers.rb | 18 + .../vcsrepo/spec/support/fixture_helpers.rb | 7 + .../unit/puppet/provider/vcsrepo/bzr_spec.rb | 109 ++ .../unit/puppet/provider/vcsrepo/cvs_spec.rb | 124 ++ .../unit/puppet/provider/vcsrepo/git_spec.rb | 401 ++++ .../unit/puppet/provider/vcsrepo/hg_spec.rb | 138 ++ .../unit/puppet/provider/vcsrepo/p4_spec.rb | 82 + .../unit/puppet/provider/vcsrepo/svn_spec.rb | 160 ++ .../spec/unit/puppet/type/README.markdown | 4 + tools/laptop_puppetisation/site.pp | 60 +- 855 files changed, 41582 insertions(+), 64 deletions(-) create mode 100644 tools/laptop_puppetisation/modules/gnupg/CHANGELOG create mode 100644 tools/laptop_puppetisation/modules/gnupg/CONTRIBUTING.md create mode 100644 tools/laptop_puppetisation/modules/gnupg/Gemfile create mode 100644 tools/laptop_puppetisation/modules/gnupg/LICENSE create mode 100644 tools/laptop_puppetisation/modules/gnupg/README.md create mode 100644 tools/laptop_puppetisation/modules/gnupg/Rakefile create mode 100644 tools/laptop_puppetisation/modules/gnupg/checksums.json create mode 100644 tools/laptop_puppetisation/modules/gnupg/files/broken.public.key create mode 100644 tools/laptop_puppetisation/modules/gnupg/files/random.key create mode 100644 tools/laptop_puppetisation/modules/gnupg/files/random.private.key create mode 100644 tools/laptop_puppetisation/modules/gnupg/files/random.public.key create mode 100644 tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_command.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_installed.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/lib/puppet/provider/gnupg_key/gnupg.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/lib/puppet/type/gnupg_key.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/gnupg/manifests/install.pp create mode 100644 tools/laptop_puppetisation/modules/gnupg/manifests/params.pp create mode 100644 tools/laptop_puppetisation/modules/gnupg/metadata.json create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/class_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/gnupg_key_install_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-59-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64-pe.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-607-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-70rc1-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-i386.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/default.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/classes/gnupg_init_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/spec.opts create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/spec_helper.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_acceptance.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_system.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/system/gnupg_key_install_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/system/install_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/spec/unit/puppet/type/gnupg_key_spec.rb create mode 100644 tools/laptop_puppetisation/modules/gnupg/tests/gnupg_key.pp create mode 100644 tools/laptop_puppetisation/modules/gnupg/tests/init.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/CHANGELOG.md create mode 100644 tools/laptop_puppetisation/modules/homebrew/Gemfile create mode 100644 tools/laptop_puppetisation/modules/homebrew/Gemfile-1.9.3 create mode 100644 tools/laptop_puppetisation/modules/homebrew/README.md create mode 100644 tools/laptop_puppetisation/modules/homebrew/checksums.json create mode 100644 tools/laptop_puppetisation/modules/homebrew/circle.yml create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/facter/has_brew.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/facter/has_compiler.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brew.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcask.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcommon.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/homebrew.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/tap.rb create mode 100644 tools/laptop_puppetisation/modules/homebrew/manifests/compiler.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/manifests/install.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/metadata.json create mode 100755 tools/laptop_puppetisation/modules/homebrew/test.sh create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/init.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/install_options.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/packages.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/tap.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/tap_priority.pp create mode 100644 tools/laptop_puppetisation/modules/homebrew/tests/token.pp create mode 100644 tools/laptop_puppetisation/modules/qahomebrew/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/qapackages/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/qarubyecosystem/manifests/init.pp create mode 100755 tools/laptop_puppetisation/modules/qavmpoolerbitbar/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/qaxcode/examples/init.pp create mode 100644 tools/laptop_puppetisation/modules/qaxcode/files/install_xcode_cli_tools.sh create mode 100644 tools/laptop_puppetisation/modules/qaxcode/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/Gemfile create mode 100644 tools/laptop_puppetisation/modules/rvm/LICENSE create mode 100644 tools/laptop_puppetisation/modules/rvm/README.markdown create mode 100644 tools/laptop_puppetisation/modules/rvm/Rakefile create mode 100644 tools/laptop_puppetisation/modules/rvm/checksums.json create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_installed.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_version.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_alias/alias.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gem/gem.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gemset/gemset.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_system_ruby/rvm_system_ruby.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_wrapper/wrapper.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_alias.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gem.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gemset.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_system_ruby.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_wrapper.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/dependencies.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/dependencies/centos.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/dependencies/oraclelinux.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/dependencies/ubuntu.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/gnupg_key.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/gpg.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/group.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/params.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/apache.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/centos.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/oraclelinux.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/ubuntu.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/passenger/gem.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/rvmrc.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/system.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/manifests/system_user.pp create mode 100644 tools/laptop_puppetisation/modules/rvm/metadata.json create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64-docker.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64-docker.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-73-x64.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/default.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64-docker.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/acceptance/rvm_system_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/dependencies_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/gnupg_key_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/gpg_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/init_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/rvmrc_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/classes/system_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_alias_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gem_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gemset_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_system_ruby_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_wrapper_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/defines/system_user_spec.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/fixtures/hiera.yaml create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/spec_helper.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/spec/spec_helper_acceptance.rb create mode 100644 tools/laptop_puppetisation/modules/rvm/templates/rvmrc.erb create mode 100644 tools/laptop_puppetisation/modules/rvm/tests/init.pp create mode 100644 tools/laptop_puppetisation/modules/software/.fixtures.yml create mode 100644 tools/laptop_puppetisation/modules/software/.gitignore create mode 100644 tools/laptop_puppetisation/modules/software/.rubocop.yml create mode 100644 tools/laptop_puppetisation/modules/software/.ruby-gemset create mode 100644 tools/laptop_puppetisation/modules/software/.travis.yml create mode 100644 tools/laptop_puppetisation/modules/software/CHANGELOG create mode 100644 tools/laptop_puppetisation/modules/software/Gemfile create mode 100644 tools/laptop_puppetisation/modules/software/LICENSE create mode 100644 tools/laptop_puppetisation/modules/software/README.md create mode 100644 tools/laptop_puppetisation/modules/software/Rakefile create mode 100644 tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/apm.rb create mode 100644 tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/appcompressed.rb create mode 100644 tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/prefpanecompressed.rb create mode 100644 tools/laptop_puppetisation/modules/software/manifests/browsers.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/browsers/chrome.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/browsers/firefox.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/database.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/database/mysqlworkbench.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/database/pgcommander.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/database/sequelpro.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/drivers.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/drivers/lanier_mpc5503.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/editors.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/editors/atom.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/editors/textmate.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/editors/textwrangler.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/editors/vim.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/entertainment.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/entertainment/vlc.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/idesdk.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/idesdk/android_studio.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/idesdk/android_tools.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/params.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/prefpanes.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/prefpanes/hosts.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/prefpanes/launchrocket.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/social.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/social/skype.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/storage.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/storage/drive.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/storage/fetch.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/storage/filezilla.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/alfred.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/controlplane.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/iterm.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/onyx.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/openconnect.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/utilities/synaptic.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/vcsscm.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/vcsscm/git.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/vcsscm/sourcetree.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/virtualization.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/virtualization/vagrant.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/virtualization/virtualbox.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/webstack.pp create mode 100644 tools/laptop_puppetisation/modules/software/manifests/webstack/anvil.pp create mode 100644 tools/laptop_puppetisation/modules/software/metadata.json create mode 100644 tools/laptop_puppetisation/modules/software/spec/classes/software_browsers_chrome_spec.rb create mode 100644 tools/laptop_puppetisation/modules/software/spec/classes/software_editors_atom_spec.rb create mode 100644 tools/laptop_puppetisation/modules/software/spec/classes/software_virtualization_virtualbox_spec.rb create mode 100644 tools/laptop_puppetisation/modules/software/spec/spec.opts create mode 100644 tools/laptop_puppetisation/modules/software/spec/spec_helper.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/CHANGELOG.md create mode 100644 tools/laptop_puppetisation/modules/stdlib/CONTRIBUTING.md create mode 100644 tools/laptop_puppetisation/modules/stdlib/Gemfile create mode 100644 tools/laptop_puppetisation/modules/stdlib/LICENSE create mode 100644 tools/laptop_puppetisation/modules/stdlib/NOTICE create mode 100644 tools/laptop_puppetisation/modules/stdlib/README.markdown create mode 100644 tools/laptop_puppetisation/modules/stdlib/README_DEVELOPER.markdown create mode 100644 tools/laptop_puppetisation/modules/stdlib/README_SPECS.markdown create mode 100644 tools/laptop_puppetisation/modules/stdlib/RELEASE_PROCESS.markdown create mode 100644 tools/laptop_puppetisation/modules/stdlib/Rakefile create mode 100644 tools/laptop_puppetisation/modules/stdlib/checksums.json create mode 100644 tools/laptop_puppetisation/modules/stdlib/examples/file_line.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/examples/has_interface_with.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/examples/has_ip_address.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/examples/has_ip_network.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/examples/init.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/facter_dot_d.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/package_provider.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/pe_version.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/puppet_settings.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/root_home.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/service_provider.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/facter/util/puppet_settings.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/deprecation.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_a.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_absolute_path.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_array.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_float.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_numeric.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_string.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/type_of.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_array.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_hash.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_integer.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_legacy.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_numeric.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_re.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_slength.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_string.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/abs.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2array.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/assert_private.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/base64.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/basename.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2num.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2str.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/camelcase.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/capitalize.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ceiling.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chomp.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chop.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/clamp.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/concat.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/convert_base.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/count.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_at.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_values.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deprecation.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/difference.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig44.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dirname.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/downcase.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/empty.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/flatten.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/floor.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getparam.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getvar.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/grep.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_key.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/hash.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/intersection.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_array.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_float.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_hash.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_integer.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_string.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/keys.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadjson.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/lstrip.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/max.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/member.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/merge.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/min.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/num2bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parsejson.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick_default.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/prefix.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/private.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/range.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reject.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reverse.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/rstrip.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_join.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_split.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shuffle.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/size.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/sort.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/squeeze.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strftime.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strip.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/suffix.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/swapcase.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/time.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type3x.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/union.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unique.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/upcase.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/uriescape.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_array.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_re.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_string.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values_at.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/zip.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/provider/file_line/ruby.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/anchor.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/file_line.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/manifests/init.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/manifests/stages.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/metadata.json create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/abs_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/anchor_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/any2array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/base64_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/bool2num_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/build_csv.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/capitalize_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ceiling_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chomp_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chop_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/clamp_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/concat_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/count_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deep_merge_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/defined_with_params_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_at_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_undef_values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_values_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deprecation_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/difference_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/dirname_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/downcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/empty_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ensure_resource_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/flatten_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/floor_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rand_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rotate_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/get_module_path_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getparam_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getvar_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/grep_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_interface_with_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_network_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_key_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/intersection_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_a_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_domain_name_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_float_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_function_available_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_integer_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ip_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv4_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv6_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_mac_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_numeric_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_keys_to_values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/keys_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadjson_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadyaml_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/lstrip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/max_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/member_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/merge_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/min_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/centos-7-x64.yml create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/debian-8-x64.yml create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/default.yml create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/centos-7.yml create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/debian-8.yml create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/ubuntu-14.04.yml create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/num2bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parsejson_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parseyaml_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_default_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/prefix_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pw_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/range_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reject_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reverse_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/rstrip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/shuffle_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/size_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/sort_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/squeeze_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2saltedsha512_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strftime_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/suffix_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/swapcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/time_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/to_bytes_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/try_get_value_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/type_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/union_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unique_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unsupported_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/upcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/uriescape_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_absolute_path_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_augeas_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_cmd_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv4_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv6_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_re_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_slength_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_at_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/acceptance/zip_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolute_path_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolutepath_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/array_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/bool_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/float_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpsurl_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpurl_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/integer_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/ip_address.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv4_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv6_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/numeric_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/string_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/unixpath_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/aliases/windowspath_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/dscacheutil/root create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/lsuser/root create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolute_path.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolutepath.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/array.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/bool.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/float.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpsurl.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpurl.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/integer.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ip_address.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv4.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv6.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/numeric.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/string.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/unixpath.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/windowspath.pp create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/abs_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/any2array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/any2bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/assert_private_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/base64_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/basename_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2num_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2str_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/camelcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/capitalize_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/ceiling_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/chomp_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/chop_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/clamp_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/concat_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/convert_base_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/count_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/deep_merge_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/defined_with_params_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_at_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_regex_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_undef_values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_values_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/deprecation_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/difference_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/dig44_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/dig_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/dirname_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/dos2unix_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/downcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/empty_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_packages_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_resource_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/flatten_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/floor_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rand_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rotate_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/get_module_path_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/getparam_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/getvar_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/grep_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/has_interface_with_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_network_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/has_key_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/intersection_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_a_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_domain_name_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_email_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_float_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_function_available.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_integer_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ip_address_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv4_address_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv6_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_mac_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_numeric_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/is_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/join_keys_to_values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/join_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/keys_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/load_module_metadata_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/loadjson_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/loadyaml_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/lstrip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/max_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/member_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/merge_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/min_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/num2bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/parsejson_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/parseyaml_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_default_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/prefix_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/private_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/pw_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/range_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/regexpescape_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/reject_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/reverse_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/rstrip_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/seeded_rand_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_escape_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_join_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_split_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/shuffle_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/size_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/sort_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/squeeze_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/str2bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/str2saltedsha512_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/strftime_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/strip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/suffix_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/swapcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/time_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/to_bytes_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/try_get_value_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/type3x_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/type_of_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/type_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/union_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/unique_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/unix2dos_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/upcase_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/uriescape_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_absolute_path_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_array_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_augeas_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_bool_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_cmd_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_email_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_hash_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_integer_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ip_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv4_address_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv6_address_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_legacy_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_numeric_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_re_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_slength_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_string_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_x509_rsa_key_pair_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/values_at_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/values_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/functions/zip_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/alias_should_to_must.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/publicize_methods.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/spec_helper.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_acceptance.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_local.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/support/shared_data.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/package_provider_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/pe_version_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/root_home_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/service_provider_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb create mode 100755 tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/absolutepath.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/absolute_path.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/array.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/bool.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/float.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/integer.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/ip_address.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/ipv4.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/ipv6.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/numeric.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/re.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/compat/string.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/httpsurl.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/httpurl.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/unixpath.pp create mode 100644 tools/laptop_puppetisation/modules/stdlib/types/windowspath.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/CHANGELOG.md create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/CONTRIBUTING.md create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/Gemfile create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/LICENSE create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/NOTICE create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/README.markdown create mode 100755 tools/laptop_puppetisation/modules/vcsrepo/Rakefile create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/checksums.json create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/branch.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/init_repo.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/local.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/remote.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/git/bare_init.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/git/clone.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/git/working_copy_init.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone_basic_auth.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/hg/init_repo.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/p4/create_client.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/p4/delete_client.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/p4/latest_client.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/p4/sync_client.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/svn/checkout.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/examples/svn/server.pp create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/type/vcsrepo.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/metadata.json create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker_helper.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/create_repo_spec.rb create mode 100755 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.crt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.key create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_660_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_753_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/centos-7-x64.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/debian-8-x64.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/default.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/centos-7.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/debian-8.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/ubuntu-14.04.yml create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/bzr_version_info.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_a.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_none.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_parents.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_tags.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/svn_info.txt create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/spec.opts create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_acceptance.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_local.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/support/filesystem_helpers.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/support/fixture_helpers.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb create mode 100644 tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/type/README.markdown diff --git a/tools/laptop_puppetisation/README.md b/tools/laptop_puppetisation/README.md index f2a31a7d..426b243e 100755 --- a/tools/laptop_puppetisation/README.md +++ b/tools/laptop_puppetisation/README.md @@ -1,12 +1,10 @@ -Manifest to Install homebrew (with git, tmux & gnupg), rvm, ruby (2.0.0, 2.2.0, 2.3.0), Bundler & Rake for each Ruby Version +Create a manifest on an agent to test the modules as part of the QA Puppetise Laptop Project Also includes a ruby file 'install_agent.rb' which does the following: - Creates User 'wilson' with password 'password' and Home Directory - Reboots Agent - Installs puppet agent (Latest) -- Install module dependencies of manifest: -- - maestrodev-rvm -- - gildas-homebrew +- Install modules from modules folder: - Copies site.pp (manifest) to /etc/puppetlabs/code/environments/production/manifests/site.pp agent How-To Use @@ -14,4 +12,4 @@ beaker-hostgenerator osx1011-64 > macosx.yml beaker --preserve --provision --hosts macosx.yml --pre-suite install_agent.rb --log-level debug After this, you can login as root and apply the manifest -Once manifest is applied, login as wilson:password and rvm etc. will be available to you \ No newline at end of file +Once manifest is applied, login as wilson:password and rvm etc. will be available to you diff --git a/tools/laptop_puppetisation/install_agent.rb b/tools/laptop_puppetisation/install_agent.rb index 3fa4c0f7..3ead9cd4 100755 --- a/tools/laptop_puppetisation/install_agent.rb +++ b/tools/laptop_puppetisation/install_agent.rb @@ -12,20 +12,34 @@ chown wilson /Users/wilson CREATE_USER -module_dependencies = ['maestrodev-rvm', 'gildas-homebrew', 'puppetlabs-vcsrepo'] +create_custom_facts = < /var/root/.profile && +export FACTERLIB=/Users/wilson/custom_facts/ && +echo "require 'facter'" > /Users/wilson/custom_facts/mac_current_user.rb && +echo "Facter.add('mac_current_user') do" >> /Users/wilson/custom_facts/mac_current_user.rb && +echo " setcode do" >> /Users/wilson/custom_facts/mac_current_user.rb && +echo " 'wilson'" >> /Users/wilson/custom_facts/mac_current_user.rb && +echo " end" >> /Users/wilson/custom_facts/mac_current_user.rb && +echo "end" >> /Users/wilson/custom_facts/mac_current_user.rb +CREATE_CUSTOM_FACTS + +module_dependencies = ['homebrew','gnupg','qahomebrew','qapackages','qarubyecosystem','qavmpoolerbitbar','qaxcode','rvm','stdlib','vcsrepo', 'software', 'vmfloaty'] test_name "Create user wilson & Installing Puppet Agent" do agents.each{ |agent| #Add user wilson:password, then reboot on agent, create_user_script + on agent, create_custom_facts agent.reboot - - #Install agent and dependent modules install_puppet_agent_on agent + module_dependencies.each do |module_name| - on agent, "puppet module install #{module_name}" + copy_module_to(agent, :source => "./modules/#{module_name}", + :target_module_path => "/etc/puppetlabs/code/environments/production/modules/", + :module_name => "#{module_name}") + #on agent, "puppet module install #{module_name}" end - scp_to(agent, 'site.pp', '/etc/puppetlabs/code/environments/production/manifests/site.pp') } end diff --git a/tools/laptop_puppetisation/modules/gnupg/CHANGELOG b/tools/laptop_puppetisation/modules/gnupg/CHANGELOG new file mode 100644 index 00000000..d4a97711 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/CHANGELOG @@ -0,0 +1,49 @@ +2016-01-22 - Dejan Golja - 1.2.3 +* Another retry to rebuild repack the module to fix the PaxHeaders bsd tar bug + +2016-01-18 - Dejan Golja - 1.2.2 +* module Remove PaxHeaders from distributed package, so it works with r10k + +2015-07-04 - Dejan Golja - 1.2.1 +* remove (present|absent) restriction on $package_ensure +* add support for SLES + +2015-05-16 - Dejan Golja - 1.2.0 +* autorequire user type when using gnupg_key (tnx to tcinel@atlassian.com) +* added two new custom facts: + * gnupg_command - get full path to gpg exe + * gnupg_installed - determine if gpg exe exists on system + +2015-03-24 - Dejan Golja - 1.1.1 +* supports username with - + +2015-02-21 - Dejan Golja - 1.1.0 +* properly supports private key (added new paramater key_type + for gnupg_key type) +* added new parameter key_content for gnupg_key type + to make it easier integrate hiera lookups. More info check README + +Special thanks to Tobias Clemson (https://github.com/tobyclemson) + +2014-10-20 - Dejan Golja - 1.0.0 +* remove support for puppet 2.7.x due to the native type +* added beaker system spec tests +* Update type definition so it uses Puppet::Util::Execution.execute + instead of Puppet::Util::SUIDManager.run_and_capture (deprecated) +* bump version to 1.0.0 + +2014-10-07 - Dejan Golja - 0.0.5 +* bugfix for https keys + +2014-08-17 - Dejan Golja - 0.0.4 +* Update metadata.json and removed Modulefile due to + as of Puppet 3.6 the Modulefile has been deprecated + +2014-03-16 - Dejan Golja - 0.0.3 +* Added Puppet Forge Search by Module Compatibility + +2013-10-22 - Dejan Golja - 0.0.2 +* public release for Forge + +2013-10-12 - Dejan Golja - 0.0.1 +* initial beta version not released to the public diff --git a/tools/laptop_puppetisation/modules/gnupg/CONTRIBUTING.md b/tools/laptop_puppetisation/modules/gnupg/CONTRIBUTING.md new file mode 100644 index 00000000..dbf159cb --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/CONTRIBUTING.md @@ -0,0 +1,216 @@ +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: + + * 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 +--------------- + +This 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://projects.puppetlabs.com/projects/puppet/wiki/Getting_Help) + +* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) + +* [Patchwork](https://patchwork.puppetlabs.com) + +* [Contributor License Agreement](https://projects.puppetlabs.com/contributor_licenses/sign) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/tools/laptop_puppetisation/modules/gnupg/Gemfile b/tools/laptop_puppetisation/modules/gnupg/Gemfile new file mode 100644 index 00000000..e37a38f6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/Gemfile @@ -0,0 +1,33 @@ +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +group :development, :test do + gem 'rake', :require => false + gem 'rspec-core','~> 3.1.7', :require => false + gem 'rspec-puppet', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'puppet-lint', :require => false + gem 'puppet_facts', :require => false + gem 'json', :require => false + gem 'metadata-json-lint', :require => false +end + +group :system_tests do + gem 'beaker', '~> 2.4', :require => false + gem 'beaker-rspec', :require => false + gem 'serverspec', :require => false + gem 'rspec-system-puppet', :require => false +end + +if facterversion = ENV['FACTER_GEM_VERSION'] + gem 'facter', facterversion, :require => false +else + gem 'facter', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/tools/laptop_puppetisation/modules/gnupg/LICENSE b/tools/laptop_puppetisation/modules/gnupg/LICENSE new file mode 100644 index 00000000..5abff44c --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting 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 2013 Dejan Golja + + 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/tools/laptop_puppetisation/modules/gnupg/README.md b/tools/laptop_puppetisation/modules/gnupg/README.md new file mode 100644 index 00000000..3ce4c796 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/README.md @@ -0,0 +1,225 @@ +#GnuPG puppet module + +####Table of Contents + +1. [Overview](##overview) +2. [Installation](##Installation) +3. [Usage - Configuration options and additional functionality](@#usage) +4. [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) +7. [License](##license) + +##Overview + +Install GnuPG on Ubuntu/Debian/RedHat/CentOS/Amazon AMI and manage users public keys. + +Tested with Tavis CI + +NOTE: For puppet 2.7.x supported module please use version 0.X.X + +[![Build Status](https://travis-ci.org/n1tr0g/golja-gnupg.png)](https://travis-ci.org/n1tr0g/golja-gnupg) [![Puppet Forge](http://img.shields.io/puppetforge/v/golja/gnupg.svg)](https://forge.puppetlabs.com/golja/gnupg) + +##Installation + + $ puppet module install golja/gnupg + +##Usage + +####Install GnuPG package + + include '::gnupg' + +####Add public key 20BC0A86 from PGP server from hkp://pgp.mit.edu/ to user root + +```puppet +gnupg_key { 'hkp_server_20BC0A86': + ensure => present, + key_id => '20BC0A86', + user => 'root', + key_server => 'hkp://pgp.mit.edu/', + key_type => public, +} +``` + +####Add public key D50582E6 from standard http URI to user foo + +```puppet +gnupg_key { 'jenkins_foo_key': + ensure => present, + key_id => 'D50582E6', + user => 'foo', + key_source => 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', + key_type => public, +} +``` + +####Add public key D50582E6 from puppet fileserver to user foo + +```puppet +gnupg_key { 'jenkins_foo_key': + ensure => present, + key_id => 'D50582E6', + user => 'foo', + key_source => 'puppet:///modules/gnupg/D50582E6.key', + key_type => public, +} +``` + +####Add public key D50582E6 from puppet fileserver to user bar via a string value + +```puppet +gnupg_key { 'jenkins_foo_key': + ensure => present, + key_id => 'D50582E6', + user => 'bar', + key_content => '-----BEGIN BROKEN PUBLIC KEY BLOCK-----...', + key_type => public, +} +``` +*Note*: You should use hiera lookup to get the key content + +####Remove public key 20BC0A86 from user root + +```puppet +gnupg_key {'root_remove': + ensure => absent, + key_id => '20BC0A86', + user => 'root', + key_type => public, +} +``` + +###Remove both private and public key 20BC0A66 + +```puppet +gnupg_key {'root_remove': + ensure => absent, + key_id => '20BC0A66', + user => 'root', + key_type => both, +} +``` + +##Reference + +###Classes + +####gnupg + +#####`package_ensure` + +Valid value present/absent. In most cases you should never uninstall this package, +because most of the modern Linux distros rely on gnupg for package verification, etc +Default: present + +#####`package_name` + +Name of the GnuPG package. Default value determined by $::osfamily/$::operatingsystem facts + +####gnupg_key + +#####`ensure` + +**REQUIRED** - Valid value present/absent + +#####`user` + +**REQUIRED** - System username for who to store the public key. Also define the location of the +pubring (default ${HOME}/.gnupg/) + +#####`key_id` + +**REQUIRED** - Key ID. Usually the traditional 8-character key ID. Also accepted the +long more accurate (but less convenient) 16-character key ID. Accept only hexadecimal +values. + +#####`key_source` + +**REQUIRED** if `key_server` or `key_content` is not defined and `ensure` is present. +A source file containing PGP key. Values can be URIs pointing to remote files, +or fully qualified paths to files available on the local system. + +The available URI schemes are *puppet*, *https*, *http* and *file*. *Puppet* +URIs will retrieve files from Puppet's built-in file server, and are +usually formatted as: + +puppet:///modules/name_of_module/filename + +#####`key_server` + +**REQUIRED** if `key_source` or `key_content` is not defined and `ensure` is present. + +PGP key server from where to retrieve the public key. Valid URI schemes are +*http*, *https*, *ldap* and *hkp*. + +#####`key_content` + +**REQUIRED** if `key_server` or `key_source` is not defined and `ensure` is present. + +Provide the content of the key as a string. This is useful when the key is stored as a +hiera property and the consumer doesn't want to have to write that content to a file +before the gnupg_key resource executes. + + +#####`key_type` + +**OPTIONAL** - key type. Valid values (public|private|both). Default: public + +PGP key server from where to retrieve the public key. Valid URI schemes are +*http*, *https*, *ldap* and *hkp*. + + +### Tests + +There are two types of tests distributed with the module. Unit tests with rspec-puppet and system tests using rspec-system or beaker. + +For unit testing, make sure you have: + +* rake +* bundler + +Install the necessary gems: + + bundle install --path=vendor + +And then run the unit tests: + + bundle exec rake spec + + +If you want to run the system tests, make sure you also have: + +* vagrant > 1.3.x +* Virtualbox > 4.2.10 + +Then run the tests using: + + bundle exec rake spec:system + +To run the tests on different operating systems, see the sets available in .nodeset.yml and run the specific set with the following syntax: + + RSPEC_SET=debian-607-x64 bundle exec rake spec:system + +Alernatively you can run beaker tests using: + + bundle exec rake beaker + +##Limitations + +This module has been tested on: + +* Debian 6/7 +* Ubuntu 12+ +* RedHat 5/6/7 +* CentOS 5/6/7 +* Amazon AMI + +##Development + +Please see CONTRIBUTING.md + +## License + +See LICENSE file + diff --git a/tools/laptop_puppetisation/modules/gnupg/Rakefile b/tools/laptop_puppetisation/modules/gnupg/Rakefile new file mode 100644 index 00000000..ed6717e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/Rakefile @@ -0,0 +1,16 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send("disable_80chars") +PuppetLint.configuration.send('disable_class_parameter_defaults') +PuppetLint.configuration.send('disable_class_inherits_from_params_class') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.ignore_paths = ["pkg/**/*", "vendor/**/*", "spec/**/*"] + +desc "Run syntax, lint, and beaker tests." +task :test => [:validate, :lint, :spec] + diff --git a/tools/laptop_puppetisation/modules/gnupg/checksums.json b/tools/laptop_puppetisation/modules/gnupg/checksums.json new file mode 100644 index 00000000..29ade300 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/checksums.json @@ -0,0 +1,45 @@ +{ + "CHANGELOG": "4257d420ca9be5119cd0425462dde946", + "CONTRIBUTING.md": "9dcdfac1fd18c823d852ffbadfd7ae6b", + "Gemfile": "b0f3c8dda2f2e290346efff54e107bec", + "LICENSE": "068b61c857ebf3d856893c6ebee97c4e", + "README.md": "e7364c08c734f1872d7565eaca15cb44", + "Rakefile": "812dc5b890322c4fe454385f2304af38", + "files/broken.public.key": "8edd6e58ae06253af930b3dec94e9e20", + "files/random.key": "ac50bb402fe879d8d6251600ba96fc51", + "files/random.private.key": "ca0ca9a6e5523f15025d577f4aed993b", + "files/random.public.key": "a3dc5a0c70fecf727dc003a392a3af37", + "lib/facter/gnupg_command.rb": "130eef96850db8a7f3fcdf6d4e616f25", + "lib/facter/gnupg_installed.rb": "15df4f80dbb3d4c403a79481a944f229", + "lib/puppet/provider/gnupg_key/gnupg.rb": "52563557974fbf6a8da2aea267c00066", + "lib/puppet/type/gnupg_key.rb": "d1a5be9c5ce65fa19b440073d6f293cf", + "manifests/init.pp": "eada8380c7a234e0ee9b87bbd7ae4bb2", + "manifests/install.pp": "a4e4b75a99f985dd3ae69de908a0bd77", + "manifests/params.pp": "03bb7e35cdd808434b01a59100954781", + "metadata.json": "3f5fef518d41806356b6c5cf141cec18", + "spec/acceptance/class_spec.rb": "a19c2ebdc67b2be5fedc5789274cf6a1", + "spec/acceptance/gnupg_key_install_spec.rb": "3142a8574ae9464ecc3ca17a7d2a212d", + "spec/acceptance/nodesets/centos-59-x64.yml": "57eb3e471b9042a8ea40978c467f8151", + "spec/acceptance/nodesets/centos-64-x64-pe.yml": "ec075d95760df3d4702abea1ce0a829b", + "spec/acceptance/nodesets/centos-64-x64.yml": "d65958bdf25fb31eb4838fd984b555df", + "spec/acceptance/nodesets/centos-65-x64.yml": "3e5c36e6aa5a690229e720f4048bb8af", + "spec/acceptance/nodesets/debian-607-x64.yml": "52f42f3b8fc507a5fc825977d62665a3", + "spec/acceptance/nodesets/debian-70rc1-x64.yml": "717aa92150ebe3fca718807c7c93126f", + "spec/acceptance/nodesets/debian-73-i386.yml": "40aeb7ceab29148bb98a1e2bd51aba86", + "spec/acceptance/nodesets/debian-73-x64.yml": "df78f357e1bd0f7f9818d552eeb35026", + "spec/acceptance/nodesets/default.yml": "d65958bdf25fb31eb4838fd984b555df", + "spec/acceptance/nodesets/ubuntu-server-10044-x64.yml": "75e86400b7889888dc0781c0ae1a1297", + "spec/acceptance/nodesets/ubuntu-server-12042-x64.yml": "d30d73e34cd50b043c7d14e305955269", + "spec/acceptance/nodesets/ubuntu-server-1310-x64.yml": "9deb39279e104d765179b471c6ebb3a2", + "spec/acceptance/nodesets/ubuntu-server-1404-x64.yml": "5f0aed10098ac5b78e4217bb27c7aaf0", + "spec/classes/gnupg_init_spec.rb": "a87238fbce7a811e7ae081c988727073", + "spec/spec.opts": "a600ded995d948e393fbe2320ba8e51c", + "spec/spec_helper.rb": "1ada069d7869a2d9223d2e6a4bf3b2a7", + "spec/spec_helper_acceptance.rb": "1d03a6dcdf0490a7d759211cd45e351e", + "spec/spec_helper_system.rb": "5a6cdd4952a3dcc1b23623a32a266dc6", + "spec/system/gnupg_key_install_spec.rb": "d43d079f8d19e4ab11d0b41c3863f742", + "spec/system/install_spec.rb": "d3a5c8e44088bec955b9564664e89031", + "spec/unit/puppet/type/gnupg_key_spec.rb": "94d14155385b681abea26ecd36e9e732", + "tests/gnupg_key.pp": "83737b98421ab1c84a91cce7bf2cf6e0", + "tests/init.pp": "e3d66cab2e4cf9338c1919a6a0aff57b" +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/gnupg/files/broken.public.key b/tools/laptop_puppetisation/modules/gnupg/files/broken.public.key new file mode 100644 index 00000000..c9169d72 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/files/broken.public.key @@ -0,0 +1,30 @@ +-----BEGIN BROKEN PUBLIC KEY BLOCK----- +Version: GnuPG/MacGPG2 v2.0.22 (Darwin) + +mQENBFTnQ0QBCACx0qbkYotSSCCGAKspC8MKO+dEkna/+DA+TQ/kdtB6LV3LLTEj +xmjz7GSThEr+0nLOv17Ox9UtmZ4arH74CKo4LGognzDvaY5xEXV5SBfQAl5pYYhy +WRL7HwyGdUgeTJK/pNU7xRS4G91DuerRJauND1z+n38P6/dIdUy9PYrYSEN3NCn5 +0CP+SplEb8fDHNlLSZgBY43p1w944+ptHnp1NCU5BfYZl+dCd10iGYIE+v9K+F2r +ZOYMAvtlT4dEU8No/kkbqo2oVlvkORGydNYKlgz2+ZnAehGhK69uPhOGlUolyKA5 +LuwZnFo937D0Ia7jIlA6sRA5pOPKbe80mjA3ABEBAAG0MVRlc3QgS2V5IChHbnVQ +RyBQdXBwZXQgTW9kdWxlKSA8dGVzdEBleGFtcGxlLmNvbT6JATgEEwECACIFAlTn +Q0QCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGATXCaSb6m50u0H/3u7 +ZVieNuCHr4NSHN/rlG04cXBU20GbRPE4xXp1HqT/17B5TgeW3nvh1swB9sTn3tQ8 +bkF0cVDi10xL8rOHnmoPCdTopZ987ZVsQoGwObHWXrpMOFhA1aHYWYDPNXxc+Hf2 +hUWflXnyqWdo00uLsRFy9KS9HisreJ1L3M1vsXHXQKsVVWrrt+Lkz9Xc4EJ2Fn/G +L336dAQTonUOPCjrgBMOnlgl3v0ApBD3PGCkqO34kzz5cOxGBkL7TN751wkbPZ1I +KAzBj0LSF5Z89PLL5Mfo6NsSouUdIbCX8sZEi6NeHL13u1jRfERUaOeuDS1gqUyb +8gKJKeNddjTSTZEyVtC5AQ0EVOdDRAEIANPfqn+qbfr8PL5wy9f0SaJJh2UmqwcH +dxZLkMQVuK+l7Gxz5qXctcDoj/DMTRGFlreH344D9QO6XGJDRDIVjS2owNf/atCY +1fF5M32BEJMKT87jg7Ycy3F+s6w9WMTuUAjok7Ojc883ph+pwqN8fT0lG64Qa0tS +oqlhx/+Q2hxEv7z6P+jHB3L4tpJsUF3Amjej4DBAkGhUWN6UgjEIaiUVjURtqzS2 +MUB22fP8hMvxUKFDkz2D490OiX2+79U9z5YrPw8FjsSjCRnCXkOBIuNRmrddAdyM +WfNx2QX+H/MPShNB+TZdXJ7eXlp5OuM/Zj/i4vzGRdEw9JemMGhCJqsAEQEAAYkB +HwQYAQIACQUCVOdDRAIbDAAKCRBgE1wmkm+puQmiB/9czjtf9srBKj3PS13rkdjO +Hc5TaswBhnJ1lRUTssGN1hxUonjwsVO3gFtgcyv1MjXPUPi6yhC+4jdhG47Ja3zi +0TFHQm3ECL6Z+YOun6ohYpUzvuoqI/H2NRM+BYlvD2fnSCgE3RUm3V8duL40CcX1 +8wGIS9Vo9/0H97XdS8tWQBLBty2LgX+LLKxzu59rEOU3pNlf09eMiJi6Riwi5gHf +m8zv8omg5bF0pjFa2MK5297wn7i0dJlqCj7Cpr/FgHlGSZFlTqeKmusVJ/J7Kl/M +pzwCDQQeWmx8WXxZ0IUTKQYjmUZrYLelWzfxbuW3ZbK8sK+GDhS6n2H0AqhHiFl6 +=LuvV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tools/laptop_puppetisation/modules/gnupg/files/random.key b/tools/laptop_puppetisation/modules/gnupg/files/random.key new file mode 100644 index 00000000..58cedf90 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/files/random.key @@ -0,0 +1,28 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.0 + +mQENBFJFfvUBCADJ0TdGQazYBrTWeTXTnzdY0AqjKY+GlqB83Qfk1BLEhEZRGYsg9R4uSFB5 +7Ey6A5JOP9TjfCflgUiifScQjtnT9492fwdxa610KFVSVlfuXAM3YwZVcxv0H7rZOQyS7lzT +jCEZnGM+9hwsa0Zo6i/b+2ZTQ8cePYK57mrdTbl8nWSfNov4h4x94D9joiyaZurC04JKuh1O +RhT2NuTg5VcyoHsMiGtcIMVnjOgM6YjY7QbaNbPN0WTzzEUQ0VWPJsE+4V0ZUbSIKLt/fTXx +3SFEBe+ECHPER0xSgMYz/v5VukSH0Pyh++mMbRESjmgDkBfd5euTx3W3bMl0KOMGMA0XABEB +AAG0JkRlamFuIERhc2ljIDxkZWphbi5kYXNpY0B2bGF0YWNvbS5jb20+iQE/BBMBAgApBQJS +RX71AhsjBQkFo5qABwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQPM6LxSC8CobrOwf/ +T80AG3az4YHNy0uFdsBhpTY/PiSk5kc22jwGYPXBmj5tbfXt3rkxurZxw/YRwLS3fyXP/3n7 +tyLLBEvTqr8pxx91LgRV4lyHv+6tGT3+DZPRp5SNxky6D74HsrYq3nk52LaMqcx235vsPrxQ +24dpmWoR8ZWWv8wxT0bK3YUO0xiAm/OMCdHp3D9QW3tOiMUuGwQ7lRDUOqEIEeBLysy7uAK7 +TbaAY3jafv4E02k0orhJwFQR7gRBg53aDzb2RtMEaYCegsHurmOr1/mgChPNlvF7sliQNJM+ +QQBeggr4qSevrPW/rARt2o03M2Gw3K9JuPkWptBnBfmgF4juSA6bgrkBDQRSRX71AQgA2V4d +FmZxKdWkeb8K80OVEi18oPx54U8mfETRuUOSo4BjoMmUVsq9pZnfM6NU226M4JhVbPDrKe5h +a6itHabeeaKRSY2LVoqzr2wJmrATHf3j7wQW3hARzsFMCLXblGCHK6Stp9rvvUxiDL0z1b6t +l/7Qw+yQO0i8O2suH2ERdNxQHqoLxp+MQD1BVekHZpdho/R4V1rX49NxuPS5XyfPXj92agXP +PoWPjeKnHioUEBXsTiP71pxdY34T8NZqR2T1lw/BFWzVufFJB/3cTiwBfaZu+pjoq4EbE7K0 +9FdR4OU4BAyzw0Q1bsA5+Y3dDoONu9iQKznM50R4myv2SFZkXwARAQABiQElBBgBAgAPBQJS +RX71AhsMBQkFo5qAAAoJEDzOi8UgvAqGnt4H/Al8RyvUBTPdaByCxhggNNlzTYLk7rPwZm0d +CryQNoI6R0CmI8/33c74y1Pwrc8fnUjddGqh5VOSJe2REBmvu/+WCZaMlMeRRPzIzW49NzPp +j1zkK8jGXoKeaWFzVPfM4tPReNBnLhTegM+buUFB/w9SvKuFnyQvmYhOEUkTdphUjoVXiztE +lp8MI78ONkKJF9yd0Gcbfv1N+ggHrKpyNh497b0P+FJMNic1cS79DVWzM08BQagl/+DgAyES +Vt6XHYw6Jvw+nzJHFkX3TylgfSRbWtnBYGxJa54aQNmS2pYW3atKRxNJjn2uiiUQWuGqhmX1 +GsCLLsqleF8Hb4O6Wag= +=vG4P +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tools/laptop_puppetisation/modules/gnupg/files/random.private.key b/tools/laptop_puppetisation/modules/gnupg/files/random.private.key new file mode 100644 index 00000000..1357b7e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/files/random.private.key @@ -0,0 +1,58 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG/MacGPG2 v2.0.22 (Darwin) + +lQOYBFTnQ0QBCACx0qbkYotSSCCGAKspC8MKO+dEkna/+DA+TQ/kdtB6LV3LLTEj +xmjz7GSThEr+0nLOv17Ox9UtmZ4arH74CKo4LGognzDvaY5xEXV5SBfQAl5pYYhy +WRL7HwyGdUgeTJK/pNU7xRS4G91DuerRJauND1z+n38P6/dIdUy9PYrYSEN3NCn5 +0CP+SplEb8fDHNlLSZgBY43p1w944+ptHnp1NCU5BfYZl+dCd10iGYIE+v9K+F2r +ZOYMAvtlT4dEU8No/kkbqo2oVlvkORGydNYKlgz2+ZnAehGhK69uPhOGlUolyKA5 +LuwZnFo937D0Ia7jIlA6sRA5pOPKbe80mjA3ABEBAAEAB/oDZ9nra4Roky9lnEiq +6hSWXcGsULPL3G3WxkoPdu5qO0kzFXlTSpRYVkbc2RPzSnDeyyUpMlmVBylTMHTk +Eje/CKwQVjbX4akpOuDe7ZsLJah3kzcg8todYMxax49AiU3m3rojbBRdVvyctJ2t +229W2HGlrMSrDOVjsrTBYRbc1TPxdym9SRZM9OU8ZVN8f7p97usIONXe1wIo6mTI +zBZBXPO1KiFgfN2ZIKPdfIgFkbXUMGwUMhAYePVSE3RlUWeuHgS0uMQsX2BVDPw6 +KIylaFyUgLXDCqzrgmi4v6IJTCbxE8LpdTbuHDGHuBKp9OseWLHSGroIxJv6APMq +lqHBBADFGxGSYqz/x9dMAGjI9SoNiSL291YiFi3MvVcNTh7tT646Nm8JazdmQEuk +N90L6zvkmgapluxU0JF90WDf5YZR72rxjAtsvjnyyIhyW8L63YJxYf/G38Kbb9Fu +hwG0Ad/3btRRqJmQYtw9D2Eh46JRF0wFlxTzjJv5miQWfZQNdwQA5vSa8/Wa0Amb +nK5671blTXnd0s9oZrEu4vTRN29iMBWbLt655QrsiXCquJVPJ9zRacduIWkvqUq6 +prx2qjRACJGItE/+ID2E7kXg1ebestXZctF1O1IHC/YjTteYQ/+WgsSLRXGofC3E +o/JxJ9J6UfJa5cFgu3UfD+5+S/oQo0ED/iTpkv8lV3cubLEySMvb44REZUb+5jHT +FAR+TC06PmkHCAKd/1LlO4Zw7n+Tl4W+QBoWjmmsVyPTxq4NJ+lINgWXzqmdG6SW +BGIpN8Trjfz0tzH5num6Etm03Izh5nIzzd2WEKQtzgeLUD6w99sINoOPiKw+lc03 +psPYsILA9fhBR6+0MVRlc3QgS2V5IChHbnVQRyBQdXBwZXQgTW9kdWxlKSA8dGVz +dEBleGFtcGxlLmNvbT6JATgEEwECACIFAlTnQ0QCGwMGCwkIBwMCBhUIAgkKCwQW +AgMBAh4BAheAAAoJEGATXCaSb6m50u0H/3u7ZVieNuCHr4NSHN/rlG04cXBU20Gb +RPE4xXp1HqT/17B5TgeW3nvh1swB9sTn3tQ8bkF0cVDi10xL8rOHnmoPCdTopZ98 +7ZVsQoGwObHWXrpMOFhA1aHYWYDPNXxc+Hf2hUWflXnyqWdo00uLsRFy9KS9Hisr +eJ1L3M1vsXHXQKsVVWrrt+Lkz9Xc4EJ2Fn/GL336dAQTonUOPCjrgBMOnlgl3v0A +pBD3PGCkqO34kzz5cOxGBkL7TN751wkbPZ1IKAzBj0LSF5Z89PLL5Mfo6NsSouUd +IbCX8sZEi6NeHL13u1jRfERUaOeuDS1gqUyb8gKJKeNddjTSTZEyVtCdA5gEVOdD +RAEIANPfqn+qbfr8PL5wy9f0SaJJh2UmqwcHdxZLkMQVuK+l7Gxz5qXctcDoj/DM +TRGFlreH344D9QO6XGJDRDIVjS2owNf/atCY1fF5M32BEJMKT87jg7Ycy3F+s6w9 +WMTuUAjok7Ojc883ph+pwqN8fT0lG64Qa0tSoqlhx/+Q2hxEv7z6P+jHB3L4tpJs +UF3Amjej4DBAkGhUWN6UgjEIaiUVjURtqzS2MUB22fP8hMvxUKFDkz2D490OiX2+ +79U9z5YrPw8FjsSjCRnCXkOBIuNRmrddAdyMWfNx2QX+H/MPShNB+TZdXJ7eXlp5 +OuM/Zj/i4vzGRdEw9JemMGhCJqsAEQEAAQAH/jwpk18MFI3D6TXEjsWEKxKHoYgx ++jeVQZYVoAZmCprp2SAUqyZm7T9ZamIciTfUAK+dx/eqHP1RgmEuq6MzJnMUK6pJ +71lLRNj8KwhUyVGPiIj9Zs2kEIrqSPe8NcQ5zYUyEZrda4moSiZMjKXiuCdQLbN4 +Gxd44BKL3wAtcBm9URH/Bkza+rDx+8a1zVGVAwoS3lSdhMBVjnGFuREkX3S48FSu +WxrL69d677CcD5pTU5L4eH/oEm/M/dVusTnKPs5rnfsGrhv5Kj6GiRr6yftkIlJB +Rr1bZHo+RQrK5K0Xx+vayb0dWlzvXQURW8CNPYnsaQWceJC6G2iAOVjNDM0EANUk +MfPb5bGYjQ4qNU1LWHd6vR/KElsmDNMxXlBMHrhH24Izl7aPMrEEEKuiYkBvrLl/ +SN4oAzQ6Kdro188PXcBOJ7dFJQxiDPa9SObOTSu4/kFMaIqxLmlUDTq30HwdgXPj +wsvBY1QWymqhmywUSDdqkY/9kqFnvJr7fL6rr2xNBAD+ejbfuiGsaNvi8eGSDQC6 +IEWoi7XHgyL7N5sXEGzcYIa6Rc8kbWahlTTsetyMpSL6WonIBzx9pbGWuqSpZuM4 +63Dott0IsZlrHXBRGs+gcUJJ1VM4Qm2B8Yr+rpWJJZ3x+n9QWDQyHPzuacGFy7nc +y21xbP+ngSB9NAfoglf61wP9GjMjrr4oPgj3rXxQXWrd+J+hUUN8DkbQbmeXfgR0 +LdFuXdVj9YHT6JDTuyzDZjgraCOJdWE3wkdyoOK3ZMYxq9ZW5Np4W9c+eQU0fIx6 +N31D+PhTh9Qzp32tQLOj2AoG+HlZhn/qFGWruNngXt3mxwthqAtYqXi71mzdYIZW +c24/k4kBHwQYAQIACQUCVOdDRAIbDAAKCRBgE1wmkm+puQmiB/9czjtf9srBKj3P +S13rkdjOHc5TaswBhnJ1lRUTssGN1hxUonjwsVO3gFtgcyv1MjXPUPi6yhC+4jdh +G47Ja3zi0TFHQm3ECL6Z+YOun6ohYpUzvuoqI/H2NRM+BYlvD2fnSCgE3RUm3V8d +uL40CcX18wGIS9Vo9/0H97XdS8tWQBLBty2LgX+LLKxzu59rEOU3pNlf09eMiJi6 +Riwi5gHfm8zv8omg5bF0pjFa2MK5297wn7i0dJlqCj7Cpr/FgHlGSZFlTqeKmusV +J/J7Kl/MpzwCDQQeWmx8WXxZ0IUTKQYjmUZrYLelWzfxbuW3ZbK8sK+GDhS6n2H0 +AqhHiFl6 +=9q5t +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tools/laptop_puppetisation/modules/gnupg/files/random.public.key b/tools/laptop_puppetisation/modules/gnupg/files/random.public.key new file mode 100644 index 00000000..794da99d --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/files/random.public.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG/MacGPG2 v2.0.22 (Darwin) + +mQENBFTnQ0QBCACx0qbkYotSSCCGAKspC8MKO+dEkna/+DA+TQ/kdtB6LV3LLTEj +xmjz7GSThEr+0nLOv17Ox9UtmZ4arH74CKo4LGognzDvaY5xEXV5SBfQAl5pYYhy +WRL7HwyGdUgeTJK/pNU7xRS4G91DuerRJauND1z+n38P6/dIdUy9PYrYSEN3NCn5 +0CP+SplEb8fDHNlLSZgBY43p1w944+ptHnp1NCU5BfYZl+dCd10iGYIE+v9K+F2r +ZOYMAvtlT4dEU8No/kkbqo2oVlvkORGydNYKlgz2+ZnAehGhK69uPhOGlUolyKA5 +LuwZnFo937D0Ia7jIlA6sRA5pOPKbe80mjA3ABEBAAG0MVRlc3QgS2V5IChHbnVQ +RyBQdXBwZXQgTW9kdWxlKSA8dGVzdEBleGFtcGxlLmNvbT6JATgEEwECACIFAlTn +Q0QCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGATXCaSb6m50u0H/3u7 +ZVieNuCHr4NSHN/rlG04cXBU20GbRPE4xXp1HqT/17B5TgeW3nvh1swB9sTn3tQ8 +bkF0cVDi10xL8rOHnmoPCdTopZ987ZVsQoGwObHWXrpMOFhA1aHYWYDPNXxc+Hf2 +hUWflXnyqWdo00uLsRFy9KS9HisreJ1L3M1vsXHXQKsVVWrrt+Lkz9Xc4EJ2Fn/G +L336dAQTonUOPCjrgBMOnlgl3v0ApBD3PGCkqO34kzz5cOxGBkL7TN751wkbPZ1I +KAzBj0LSF5Z89PLL5Mfo6NsSouUdIbCX8sZEi6NeHL13u1jRfERUaOeuDS1gqUyb +8gKJKeNddjTSTZEyVtC5AQ0EVOdDRAEIANPfqn+qbfr8PL5wy9f0SaJJh2UmqwcH +dxZLkMQVuK+l7Gxz5qXctcDoj/DMTRGFlreH344D9QO6XGJDRDIVjS2owNf/atCY +1fF5M32BEJMKT87jg7Ycy3F+s6w9WMTuUAjok7Ojc883ph+pwqN8fT0lG64Qa0tS +oqlhx/+Q2hxEv7z6P+jHB3L4tpJsUF3Amjej4DBAkGhUWN6UgjEIaiUVjURtqzS2 +MUB22fP8hMvxUKFDkz2D490OiX2+79U9z5YrPw8FjsSjCRnCXkOBIuNRmrddAdyM +WfNx2QX+H/MPShNB+TZdXJ7eXlp5OuM/Zj/i4vzGRdEw9JemMGhCJqsAEQEAAYkB +HwQYAQIACQUCVOdDRAIbDAAKCRBgE1wmkm+puQmiB/9czjtf9srBKj3PS13rkdjO +Hc5TaswBhnJ1lRUTssGN1hxUonjwsVO3gFtgcyv1MjXPUPi6yhC+4jdhG47Ja3zi +0TFHQm3ECL6Z+YOun6ohYpUzvuoqI/H2NRM+BYlvD2fnSCgE3RUm3V8duL40CcX1 +8wGIS9Vo9/0H97XdS8tWQBLBty2LgX+LLKxzu59rEOU3pNlf09eMiJi6Riwi5gHf +m8zv8omg5bF0pjFa2MK5297wn7i0dJlqCj7Cpr/FgHlGSZFlTqeKmusVJ/J7Kl/M +pzwCDQQeWmx8WXxZ0IUTKQYjmUZrYLelWzfxbuW3ZbK8sK+GDhS6n2H0AqhHiFl6 +=LuvV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_command.rb b/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_command.rb new file mode 100644 index 00000000..fd9462d6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_command.rb @@ -0,0 +1,18 @@ +# Fact: gnupg_command +# +# Purpose: get full path to gpg exe +# +# Resolution: +# Tests for presence of gpg, returns nil if not present +# returns output of which gpg +# +# Caveats: +# none +# +# Notes: +# None +Facter.add(:gnupg_command) do + setcode do + Facter::Util::Resolution.which('gpg') + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_installed.rb b/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_installed.rb new file mode 100644 index 00000000..54eba47f --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/lib/facter/gnupg_installed.rb @@ -0,0 +1,18 @@ +# Fact: gnupg_installed +# +# Purpose: determine if gpg exe exists on system +# +# Resolution: +# Tests for presence of gpg, returns false if not present +# returns true if which gpg finds an exe +# +# Caveats: +# none +# +# Notes: +# None +Facter.add(:gnupg_installed) do + setcode do + !Facter.value(:gnupg_command).nil? + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/lib/puppet/provider/gnupg_key/gnupg.rb b/tools/laptop_puppetisation/modules/gnupg/lib/puppet/provider/gnupg_key/gnupg.rb new file mode 100644 index 00000000..d206d50f --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/lib/puppet/provider/gnupg_key/gnupg.rb @@ -0,0 +1,166 @@ +require 'etc' +require 'tmpdir' +require 'puppet/file_serving/content' + +Puppet::Type.type(:gnupg_key).provide(:gnupg) do + + @doc = 'Provider for gnupg_key type.' + + defaultfor :kernel => 'Linux' + confine :kernel => 'Linux' + + def self.instances + [] + end + + # although we do not use the commands class it's used to detect if the gpg and awk commands are installed on the system + commands :gpg => 'gpg' + commands :awk => 'awk' + + def remove_key + begin + fingerprint_command = "gpg --fingerprint --with-colons #{resource[:key_id]} | awk -F: '$1 == \"fpr\" {print $10;}'" + fingerprint = Puppet::Util::Execution.execute(fingerprint_command, :uid => user_id) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Could not determine fingerprint for #{resource[:key_id]} for user #{resource[:user]}: #{fingerprint}" + end + + if resource[:key_type] == :public + command = "gpg --batch --yes --delete-key #{fingerprint}" + elsif resource[:key_type] == :private + command = "gpg --batch --yes --delete-secret-key #{fingerprint}" + elsif resource[:key_type] == :both + command = "gpg --batch --yes --delete-secret-and-public-key #{fingerprint}" + end + + begin + output = Puppet::Util::Execution.execute(command, :uid => user_id) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Could not remove #{resource[:key_id]} for user #{resource[:user]}: #{output}" + end + end + + # where most of the magic happens + # TODO implement dry-run to check if the key_id match the content of the file + def add_key + if resource[:key_server] + add_key_from_key_server + elsif resource[:key_source] + add_key_from_key_source + elsif resource[:key_content] + add_key_from_key_content + end + end + + def add_key_from_key_server + command = "gpg --keyserver #{resource[:key_server]} --recv-keys #{resource[:key_id]}" + begin + output = Puppet::Util::Execution.execute(command, :uid => user_id, :failonfail => true) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Key #{resource[:key_id]} does not exist on #{resource[:key_server]}" + end + end + + def add_key_from_key_source + if Puppet::Util.absolute_path?(resource[:key_source]) + add_key_at_path + else + add_key_at_url + end + end + + def add_key_from_key_content + path = create_temporary_file(user_id, resource[:key_content]) + command = "gpg --import #{path}" + begin + output = Puppet::Util::Execution.execute(command, :uid => user_id, :failonfail => true) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Error while importing key #{resource[:key_id]} using key content:\n#{output}}" + end + end + + def add_key_at_path + if File.file?(resource[:key_source]) + command = "gpg --import #{resource[:key_source]}" + begin + output = Puppet::Util::Execution.execute(command, :uid => user_id, :failonfail => true) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Error while importing key #{resource[:key_id]} from #{resource[:key_source]}" + end + elsif + raise Puppet::Error, "Local file #{resource[:key_source]} for #{resource[:key_id]} does not exists" + end + end + + def add_key_at_url + uri = URI.parse(URI.escape(resource[:key_source])) + case uri.scheme + when /https/ + command = "wget -O- #{resource[:key_source]} | gpg --import" + when /http/ + command = "gpg --fetch-keys #{resource[:key_source]}" + when 'puppet' + path = create_temporary_file user_id, puppet_content + command = "gpg --import #{path}" + end + begin + output = Puppet::Util::Execution.execute(command, :uid => user_id, :failonfail => true) + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Error while importing key #{resource[:key_id]} from #{resource[:key_source]}:\n#{output}}" + end + end + + def user_id + begin + Etc.getpwnam(resource[:user]).uid + rescue => e + raise Puppet::Error, "User #{resource[:user]} does not exists" + end + end + + def create_temporary_file user_id, content + Puppet::Util::SUIDManager.asuser(user_id) do + tmpfile = Tempfile.open(['golja-gnupg', 'key']) + tmpfile.write(content) + tmpfile.flush + break tmpfile.path.to_s + end + end + + def puppet_content + # Look up (if necessary) and return remote content. + return @content if @content + unless tmp = Puppet::FileServing::Content.indirection.find(resource[:key_source], :environment => resource.catalog.environment, :links => :follow) + fail "Could not find any content at %s" % resource[:key_source] + end + @content = tmp.content + end + + def exists? + # public and both can be grouped since private can't be present without public, + # both only applies to delete and delete still has something to do if only + # one of the keys is present + if resource[:key_type] == :public || resource[:key_type] == :both + command = "gpg --list-keys --with-colons #{resource[:key_id]}" + elsif resource[:key_type] == :private + command = "gpg --list-secret-keys --with-colons #{resource[:key_id]}" + end + + output = Puppet::Util::Execution.execute(command, :uid => user_id) + if output.exitstatus == 0 + return true + elsif output.exitstatus == 2 + return false + else + raise Puppet::Error, "Non recognized exit status from GnuPG #{output.exitstatus} #{output}" + end + end + + def create + add_key + end + + def destroy + remove_key + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/lib/puppet/type/gnupg_key.rb b/tools/laptop_puppetisation/modules/gnupg/lib/puppet/type/gnupg_key.rb new file mode 100644 index 00000000..510e958a --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/lib/puppet/type/gnupg_key.rb @@ -0,0 +1,153 @@ +require 'uri' +Puppet::Type.newtype(:gnupg_key) do + @doc = "Manage PGP public keys with GnuPG" + + ensurable + + autorequire(:package) do + ["gnupg", "gnupg2"] + end + + autorequire(:user) do + self[:user] + end + + KEY_SOURCES = [:key_source, :key_server, :key_content] + + KEY_CONTENT_REGEXES = { + :public => ["-----BEGIN PGP PUBLIC KEY BLOCK-----", "-----END PGP PUBLIC KEY BLOCK-----"], + :private => ["-----BEGIN PGP PRIVATE KEY BLOCK-----", "-----END PGP PRIVATE KEY BLOCK-----"] + } + + validate do + creator_count = 0 + KEY_SOURCES.each do |param| + creator_count += 1 unless self[param].nil? + end + + if creator_count > 1 + raise ArgumentError, "You cannot specify more than one of #{KEY_SOURCES.collect { |p| p.to_s}.join(", ")}, " + + "much to learn, you still have." + end + + if creator_count == 0 && self[:ensure] == :present + raise ArgumentError, "You need to specify at least one of #{KEY_SOURCES.collect { |p| p.to_s}.join(", ")}, " + + "much to learn, you still have." + end + + if self[:ensure] == :present && self[:key_type] == :both + raise ArgumentError, "A key type of 'both' is invalid when ensure is 'present'." + end + + [:public, :private].each do |type| + if self[:key_content] && self[:key_type] == type + key_lines = self[:key_content].strip.lines.to_a + + first_line = key_lines.first.strip + last_line = key_lines.last.strip + + unless first_line == KEY_CONTENT_REGEXES[type][0] && last_line == KEY_CONTENT_REGEXES[type][1] + raise ArgumentError, "Provided key content does not look like a #{type} key." + end + end + end + end + + newparam(:name, :namevar => true) do + desc "This attribute is currently used as a + system-wide primary key - namevar and therefore has to be unique." + end + + newparam(:user) do + desc "The user account in which the PGP public key should be installed. + Usually it's stored in HOME/.gnupg/ dir" + + validate do |value| + # freebsd/linux username limitation + unless value =~ /^[a-z_][a-z0-9_-]*[$]?/ + raise ArgumentError, "Invalid username format for #{value}" + end + end + end + + newparam(:key_source) do + desc <<-'EOT' + A source file containing PGP key. Values can be URIs pointing to remote files, + or fully qualified paths to files available on the local system. + + The available URI schemes are *puppet*, *https*, *http* and *file*. *Puppet* + URIs will retrieve files from Puppet's built-in file server, and are + usually formatted as: + + `puppet:///modules/name_of_module/filename` + EOT + + validate do |source| + + raise ArgumentError, "Arrays not accepted as an source parameter" if source.is_a?(Array) + break if Puppet::Util.absolute_path?(source) + + begin + uri = URI.parse(URI.escape(source)) + rescue => detail + raise ArgumentError, "Could not understand source #{source}: #{detail}" + end + + raise ArgumentError, "Cannot use relative URLs '#{source}'" unless uri.absolute? + raise ArgumentError, "Cannot use opaque URLs '#{source}'" unless uri.hierarchical? + raise ArgumentError, "Cannot use URLs of type '#{uri.scheme}' as source for fileserving" unless %w{file puppet https http}.include?(uri.scheme) + end + + munge do |source| + if %w{file}.include?(URI.parse(URI.escape(source)).scheme) + URI.parse(URI.escape(source)).path + else + source + end + end + + end + + newparam(:key_server) do + desc "PGP key server from where to retrieve the public key" + + validate do |server| + if server + uri = URI.parse(URI.escape(server)) + unless uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) || + uri.is_a?(URI::LDAP) || %w{hkp}.include?(uri.scheme) + raise ArgumentError, "Invalid keyserver value #{server}" + end + end + end + + end + + newparam(:key_content) do + desc "Key content. The result of exporting the key using ASCII armor. + Can be either a public or private key." + end + + newparam(:key_id) do + desc "Key ID. Usually the traditional 8-character key ID. Also accepted the + long more accurate (but less convenient) 16-character key ID." + + validate do |value| + unless (value.length == 8 or value.length == 16) and value =~ /^[0-9A-Fa-f]+$/ + raise ArgumentError, "Invalid key id #{value}" + end + end + + munge do |value| + value.upcase.intern + end + end + + newparam(:key_type) do + desc "The type of the key(s) being managed." + + newvalues(:public, :private, :both) + + defaultto :public + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/manifests/init.pp b/tools/laptop_puppetisation/modules/gnupg/manifests/init.pp new file mode 100644 index 00000000..427d8f78 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/manifests/init.pp @@ -0,0 +1,29 @@ +# == Class: gnupg +# +# Manage gnupg and public key entries +# +# === Parameters +# +# [*package_ensure*] +# Remove or install the s3tools package. Possible values +# present or absent, however most of modern Linux distros relays on +# gnupg so you shouldn't remove the package +# +# [*package_name*] +# name of the package usually gnupg/gnupg2 depends of the distro +# +# === Examples +# +# include gnupg +# +# === Authors +# +# Dejan Golja +# +class gnupg( + $package_ensure = $gnupg::params::package_ensure, + $package_name = $gnupg::params::package_name, +) inherits gnupg::params { + + class {'::gnupg::install': } +} diff --git a/tools/laptop_puppetisation/modules/gnupg/manifests/install.pp b/tools/laptop_puppetisation/modules/gnupg/manifests/install.pp new file mode 100644 index 00000000..19167946 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/manifests/install.pp @@ -0,0 +1,9 @@ +# +class gnupg::install { + + package { 'gnupg': + ensure => $gnupg::package_ensure, + name => $gnupg::package_name, + } + +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/gnupg/manifests/params.pp b/tools/laptop_puppetisation/modules/gnupg/manifests/params.pp new file mode 100644 index 00000000..70e5773c --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/manifests/params.pp @@ -0,0 +1,30 @@ +# PRIVATE CLASS: do not use directly +class gnupg::params { + + $package_ensure = 'present' + + case $::osfamily { + 'Debian': { + $package_name ='gnupg' + } + 'RedHat': { + $package_name = 'gnupg2' + } + 'Suse': { + $package_name = 'gpg2' + } + + 'Linux': { + if $::operatingsystem == 'Amazon' { + $package_name = 'gnupg2' + } + else { + fail("Osfamily ${::osfamily} with operating system ${::operatingsystem} is not supported") + } + } + default: { + fail("Osfamily ${::osfamily} is not supported") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/gnupg/metadata.json b/tools/laptop_puppetisation/modules/gnupg/metadata.json new file mode 100644 index 00000000..d613579e --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/metadata.json @@ -0,0 +1,67 @@ +{ + "name": "golja-gnupg", + "version": "1.2.3", + "author": "Dejan Golja", + "summary": "Manage gnupg package and public keys", + "license": "Apache-2.0", + "source": "git://github.com/n1tr0g/golja-gnupg.git", + "project_page": "https://github.com/n1tr0g/golja-gnupg", + "issues_url": "https://github.com/n1tr0g/golja-gnupg/issues", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "11", + "12" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04" + ] + } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">=3.0.0 <4.0.0" + }, + { + "name": "pe", + "version_requirement": ">=3.0.0 <4.0.0" + } + ], + "tags": [ + "gnupg", + "pgp" + ], + "dependencies": [ + + ] +} diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/class_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/class_spec.rb new file mode 100644 index 00000000..c0cc09b3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/class_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper_acceptance' + +describe 'gnupg class', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + case fact('osfamily') + when 'RedHat' + package_name = 'gnupg2' + when 'Debian' + package_name = 'gnupg' + end + + context 'default parameters' do + it 'should work with no errors' do + pp = <<-EOS + class { 'gnupg': } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero + end + + describe package(package_name) do + it { is_expected.to be_installed } + end + + end + +end \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/gnupg_key_install_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/gnupg_key_install_spec.rb new file mode 100644 index 00000000..b514dd10 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/gnupg_key_install_spec.rb @@ -0,0 +1,388 @@ +require 'spec_helper_acceptance' + +describe 'install gnupg keys' do + before :all do + pp = "class { 'gnupg': }" + apply_manifest(pp, :catch_failures => true) + end + + it 'should install a public key from a http URL address' do + pp = <<-EOS + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_type => public, + key_source => 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', + key_id => 'D50582E6', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys D50582E6") do |r| + expect(r.stdout).to match(/D50582E6/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 150FDE3F7787E7D11EF4E12A9B7D32F2D50582E6") {} + end + + it 'should install a public key from a https URL address' do + pp = <<-EOS + gnupg_key { 'newrelic_key': + ensure => present, + user => 'root', + key_type => public, + key_source => 'https://download.newrelic.com/548C16BF.gpg', + key_id => '548C16BF', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 548C16BF") do |r| + expect(r.stdout).to match(/548C16BF/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key B60A3EC9BC013B9C23790EC8B31B29E5548C16BF") {} + end + + it 'should install a public key from a key server' do + pp = <<-EOS + gnupg_key { 'root_key_foo': + ensure => present, + user => 'root', + key_type => public, + key_server => 'hkp://pgp.mit.edu/', + key_id => '20BC0A86', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 20BC0A86") do |r| + expect(r.stdout).to match(/20BC0A86/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 58AA73E230EB06B2A2DE8A873CCE8BC520BC0A86") {} + end + + + it 'should delete a public key' do + scp_to master, 'files/random.public.key', '/tmp/random.public.key' + gpg("--import /tmp/random.public.key") {} + + pp = <<-EOS + gnupg_key { 'bye_bye_key': + ensure => absent, + user => root, + key_type => public, + key_id => 926FA9B9, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg deleted the key + gpg("--list-keys 926FA9B9", :acceptable_exit_codes => [0, 2]) do |r| + expect(r.stdout).to_not match(/926FA9B9/) + end + end + + it 'should install public key from the puppet fileserver/module repository' do + pp = <<-EOS + gnupg_key { 'add_key_by_remote_source': + ensure => present, + user => root, + key_type => public, + key_id => 926FA9B9, + key_source => "puppet:///modules/gnupg/random.public.key", + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") {} + end + + it 'should install public key from a local file path' do + scp_to master, 'files/random.public.key', '/tmp/random.public.key' + + pp = <<-EOS + gnupg_key { 'add_key_by_local_file_path': + ensure => present, + user => root, + key_type => public, + key_id => 926FA9B9, + key_source => "/tmp/random.public.key", + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") {} + end + + it 'should install public key from a local file URL address' do + scp_to master, 'files/random.public.key', '/tmp/random.public.key' + + pp = <<-EOS + gnupg_key { 'add_key_by_local_file_url': + ensure => present, + user => root, + key_type => public, + key_id => 926FA9B9, + key_source => "file:///tmp/random.public.key", + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") {} + end + + it 'should install public key using string key content' do + key = File.read('files/random.public.key') + + pp = <<-EOS + gnupg_key { 'public_key_from_string_content': + ensure => present, + user => root, + key_id => 926FA9B9, + key_type => public, + key_content => "#{key}" + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") {} + end + + + it 'should not install public key using string because key content is invalid' do + key = File.read('files/broken.public.key') + + pp = <<-EOS + gnupg_key { 'public_key_from_invalid_string_content': + ensure => present, + user => root, + key_id => 926FA9B9, + key_type => public, + key_content => "#{key}" + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + it 'should not install a key, because local resource does not exists' do + pp = <<-EOS + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_type => public, + key_source => '/santa/claus/does/not/exists/org/sorry/kids.key', + key_id => '40404040', + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + it 'should fail to install a public key, because there is no content at the supplied URL address' do + pp = <<-EOS + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_type => public, + key_source => 'http://foo.com/key-not-there.key', + key_id => '40404040', + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + it 'should install private key from a local file path' do + scp_to master, 'files/random.private.key', '/tmp/random.private.key' + + pp = <<-EOS + gnupg_key { 'add_private_key_by_local_file_path': + ensure => present, + user => root, + key_id => 926FA9B9, + key_type => private, + key_source => '/tmp/random.private.key' + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-secret-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-secret-and-public-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") + end + + it 'should install private key from a local file URL address' do + scp_to master, 'files/random.private.key', '/tmp/random.private.key' + + pp = <<-EOS + gnupg_key { 'add_private_key_by_local_file_path': + ensure => present, + user => root, + key_id => 926FA9B9, + key_type => private, + key_source => 'file:///tmp/random.private.key' + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-secret-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-secret-and-public-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") + end + + it 'should install private key using string key content' do + key = File.read('files/random.private.key') + + pp = <<-EOS + gnupg_key { 'private_key_from_string_content': + ensure => present, + user => root, + key_id => 926FA9B9, + key_type => private, + key_content => "#{key}" + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg installed the key + gpg("--list-secret-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-secret-and-public-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") {} + end + + it 'should delete a private key' do + # importing a private key imports the public key as well + scp_to master, 'files/random.private.key', '/tmp/random.private.key' + gpg("--import /tmp/random.private.key") {} + + pp = <<-EOS + gnupg_key { 'bye_bye_key': + ensure => absent, + user => root, + key_id => 926FA9B9, + key_type => private + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg deleted the public key + gpg("--list-secret-keys 926FA9B9", :acceptable_exit_codes => [0, 2]) do |r| + expect(r.stdout).to_not match(/926FA9B9/) + end + + # check that gnupg left the public key + gpg("--list-keys 926FA9B9") do |r| + expect(r.stdout).to match(/926FA9B9/) + expect(r.exit_code).to eq(0) + end + + # clean up + gpg("--batch --delete-key 7F2A6D3944CDFE31A47ECC2A60135C26926FA9B9") + end + + it 'should delete both public and private key for key_id' do + # importing a private key imports the public key as well + scp_to master, 'files/random.private.key', '/tmp/random.private.key' + gpg("--import /tmp/random.private.key") {} + + pp = <<-EOS + gnupg_key { 'bye_bye_key': + ensure => absent, + user => root, + key_id => 926FA9B9, + key_type => both + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + + # check that gnupg deleted the public key + gpg("--list-secret-keys 926FA9B9", :acceptable_exit_codes => [0, 2]) do |r| + expect(r.stdout).to_not match(/926FA9B9/) + end + + # check that gnupg left the public key + gpg("--list-keys 926FA9B9", :acceptable_exit_codes => [0, 2]) do |r| + expect(r.stdout).to_not match(/926FA9B9/) + end + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-59-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-59-x64.yml new file mode 100644 index 00000000..2ad90b86 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-59-x64.yml @@ -0,0 +1,10 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64-pe.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64-pe.yml new file mode 100644 index 00000000..7d9242f1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64-pe.yml @@ -0,0 +1,12 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64.yml new file mode 100644 index 00000000..ce47212a --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-64-x64.yml @@ -0,0 +1,11 @@ +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: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-65-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-65-x64.yml new file mode 100644 index 00000000..4e2cb809 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/centos-65-x64.yml @@ -0,0 +1,10 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-607-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-607-x64.yml new file mode 100644 index 00000000..e642e099 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-607-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-607-x64: + roles: + - master + platform: debian-6-amd64 + box : debian-607-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-607-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-70rc1-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-70rc1-x64.yml new file mode 100644 index 00000000..cbbbfb2c --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-70rc1-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-70rc1-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-70rc1-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-70rc1-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-i386.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-i386.yml new file mode 100644 index 00000000..a38902d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-i386.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-73-i386: + roles: + - master + platform: debian-7-i386 + box : debian-73-i386-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-i386-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-x64.yml new file mode 100644 index 00000000..f9cf0c9b --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/debian-73-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-73-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-73-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/default.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/default.yml new file mode 100644 index 00000000..ce47212a --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/default.yml @@ -0,0 +1,11 @@ +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: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml new file mode 100644 index 00000000..5ca1514e --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml @@ -0,0 +1,10 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml new file mode 100644 index 00000000..d065b304 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml @@ -0,0 +1,10 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml new file mode 100644 index 00000000..f4b2366f --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-server-1310-x64: + roles: + - master + platform: ubuntu-13.10-amd64 + box : ubuntu-server-1310-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-1310-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level : debug + type: git diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 00000000..cba1cd04 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,11 @@ +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/tools/laptop_puppetisation/modules/gnupg/spec/classes/gnupg_init_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/classes/gnupg_init_spec.rb new file mode 100644 index 00000000..08386837 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/classes/gnupg_init_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe 'gnupg', :type => :class do + + ['RedHat', 'Debian', 'Linux', 'Suse'].each do |system| + if system == 'Linux' + let(:facts) {{ :osfamily => 'Linux', :operatingsystem => 'Amazon' }} + else + let(:facts) {{ :osfamily => system }} + end + + it { expect contain_class('gnupg::install') } + + describe "gnupg on system #{system}" do + + context "when enabled" do + let(:params) {{ + :package_ensure => 'present', + :package_name => 'gnupg' + }} + + it { expect contain_package('gnupg').with({ + 'ensure' => 'present'}) + } + end + + context 'when disabled' do + let(:params) {{ + :package_ensure => 'absent', + :package_name => 'gnupg' + }} + + it { expect contain_package('gnupg').with({ + 'ensure' => 'absent'}) + } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/spec.opts b/tools/laptop_puppetisation/modules/gnupg/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper.rb b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper.rb new file mode 100644 index 00000000..f64ca3ea --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper.rb @@ -0,0 +1,3 @@ +require 'rubygems' +require 'puppetlabs_spec_helper/module_spec_helper' + diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_acceptance.rb b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_acceptance.rb new file mode 100644 index 00000000..a3c593d1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_acceptance.rb @@ -0,0 +1,48 @@ +require 'beaker-rspec/spec_helper' +require 'beaker-rspec/helpers/serverspec' + + +unless ENV['RS_PROVISION'] == 'no' + # This will install the latest available package on el and deb based + # systems fail on windows and osx, and install via gem on other *nixes + foss_opts = { :default_action => 'gem_install' } + if default.is_pe?; then install_pe; else install_puppet( foss_opts ); end + + hosts.each do |host| + if host['platform'] =~ /debian/ + on host, 'echo \'export PATH=/var/lib/gems/1.8/bin/:${PATH}\' >> ~/.bashrc' + end + + on host, "mkdir -p #{host['distmoduledir']}" + end +end + +UNSUPPORTED_PLATFORMS = ['Suse','windows','AIX','Solaris'] + +module LocalHelpers + def gpg(gpg_cmd, options = {:user => 'root', :acceptable_exit_codes => [0]}, &block) + user = options.delete(:user) + gpg = "gpg #{gpg_cmd}" + shell("su #{user} -c \"#{gpg}\"", options, &block) + end +end + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Include in our local helpers, because some puppet images run + # as diffrent users + c.include ::LocalHelpers + + # Configure all nodes in nodeset + c.before :suite do + # Install module and dependencies + hosts.each do |host| + copy_module_to(host, :source => proj_root, :module_name => 'gnupg') + end + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_system.rb b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_system.rb new file mode 100644 index 00000000..e37e880c --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/spec_helper_system.rb @@ -0,0 +1,66 @@ +require 'rspec-system/spec_helper' +require 'rspec-system-puppet/helpers' +require 'rspec-system-serverspec/helpers' +require 'tempfile' + +include Serverspec::Helper::RSpecSystem +include Serverspec::Helper::DetectOS +include RSpecSystemPuppet::Helpers + +class String + # Provide ability to remove indentation from strings, for the purpose of + # left justifying heredoc blocks. + def unindent + gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "") + end +end + +module LocalHelpers + include RSpecSystem::Util + + def gpg(gpg_cmd, user = 'root', &block) + gpg = "gpg #{gpg_cmd}" + shell("su #{shellescape(user)} -c #{shellescape(gpg)}", &block) + end +end + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Enable colour + c.tty = true + + # Include in our local helpers, because some puppet images run + # as diffrent users + c.include ::LocalHelpers + + # Puppet helpers + c.include RSpecSystemPuppet::Helpers + c.extend RSpecSystemPuppet::Helpers + + # This is where we 'setup' the nodes before running our tests + c.before :suite do + # Install puppet + puppet_install + + # Install my module from the current working copy + puppet_module_install(:source => proj_root, :module_name => 'gnupg') + shell 'whoami' + shell 'puppet module list' + + # disable hiera warnings + file = Tempfile.new('foo') + begin + file.write(<<-EOS) +--- +:logger: noop + EOS + file.close + rcp(:sp => file.path, :dp => '/etc/puppet/hiera.yaml') + ensure + file.unlink + end + end +end + diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/system/gnupg_key_install_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/system/gnupg_key_install_spec.rb new file mode 100644 index 00000000..775a08d3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/system/gnupg_key_install_spec.rb @@ -0,0 +1,152 @@ +require 'spec_helper_system' + +describe 'gnupg_key install' do + + before :all do + puppet_apply("class {'gnupg': } ") do |r| + r.exit_code.should == 0 + end + end + + it 'should install a public key from a HTTP URL address' do + pp = <<-EOS.unindent + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_source => 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', + key_id => 'D50582E6', + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 2 + r.refresh + r.exit_code.should == 0 + end + + # check that gnupg installed the key + gpg("--list-keys D50582E6") do |r| + r.stdout.should =~ /D50582E6/ + r.stderr.should == '' + r.exit_code == 0 + end + end + + it 'should install a public key from a HTTPS URL address' do + pp = <<-EOS.unindent + gnupg_key { 'newrelic_key': + ensure => present, + user => 'root', + key_source => 'https://download.newrelic.com/548C16BF.gpg', + key_id => '548C16BF', + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 2 + r.refresh + r.exit_code.should == 0 + end + + # check that gnupg installed the key + gpg("--list-keys 548C16BF") do |r| + r.stdout.should =~ /548C16BF/ + r.stderr.should == '' + r.exit_code == 0 + end + end + + it 'should install a public key from a key server' do + pp = <<-EOS.unindent + gnupg_key { 'root_key_foo': + ensure => present, + user => 'root', + key_server => 'hkp://pgp.mit.edu/', + key_id => '20BC0A86', + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 2 + r.refresh + r.exit_code.should == 0 + end + + # check that gnupg installed the key + gpg("--list-keys 20BC0A86") do |r| + r.stdout.should =~ /20BC0A86/ + r.stderr.should == '' + r.exit_code == 0 + end + end + + it 'should remove public key 20BC0A86' do + pp = <<-EOS.unindent + gnupg_key { 'bye_bye_key': + ensure => absent, + key_id => 20BC0A86, + user => root, + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 2 + r.refresh + r.exit_code.should == 0 + end + end + + it 'should install public key from the puppet fileserver/module repository' do + pp = <<-EOS.unindent + gnupg_key {'add_key_by_remote_source': + ensure => present, + key_id => 20BC0A86, + user => root, + key_source => "puppet:///modules/gnupg/random.key", + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 2 + r.refresh + r.exit_code.should == 0 + end + + # check that gnupg installed the key + gpg("--list-keys 20BC0A86") do |r| + r.stdout.should =~ /20BC0A86/ + r.stderr.should == '' + r.exit_code == 0 + end + end + + it 'should not install a public key, because local resource does not exists' do + pp = <<-EOS.unindent + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_source => '/santa/claus/does/not/exists/org/sorry/kids.key', + key_id => '40404040', + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 4 + end + end + + it 'should fail to install a public key, because there is no content at the supplied URL address' do + pp = <<-EOS.unindent + gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_source => 'http://foo.com/key-not-there.key', + key_id => '40404040', + } + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 4 + end + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/system/install_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/system/install_spec.rb new file mode 100644 index 00000000..1a4e9061 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/system/install_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper_system' + +describe 'install gnupg:' do + + it 'test loading class with no arguments' do + pp = <<-EOS.unindent + class {'gnupg':} + EOS + + puppet_apply(pp) do |r| + r.exit_code.should == 0 + r.refresh + r.exit_code.should == 0 + end + end +end diff --git a/tools/laptop_puppetisation/modules/gnupg/spec/unit/puppet/type/gnupg_key_spec.rb b/tools/laptop_puppetisation/modules/gnupg/spec/unit/puppet/type/gnupg_key_spec.rb new file mode 100644 index 00000000..ff61e92c --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/spec/unit/puppet/type/gnupg_key_spec.rb @@ -0,0 +1,127 @@ +require 'puppet' +require 'puppet/type/gnupg_key' +describe Puppet::Type.type(:gnupg_key) do + + before :each do + @gnupg_key = Puppet::Type.type(:gnupg_key).new(:name => 'foo') + end + + it 'should accept a user' do + @gnupg_key[:user] = 'root' + expect(@gnupg_key[:user]).to eq 'root' + end + + it 'should require a key_source or key_server if ensure present' do + expect { + Puppet::Type.type(:gnupg_key).new(:name => 'foo', :user => 'root', :ensure => 'present') + }.to raise_error(/You need to specify at least one of*/) + end + + it 'should ignore key_source or key_server value if ensure absent' do + @gnupg_key[:ensure] = 'absent' + expect(@gnupg_key[:ensure]). to eq :absent + end + + it 'should require a name' do + expect { + Puppet::Type.type(:gnupg_key).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + + it 'should not allow invalid formated user' do + expect { + @gnupg_key[:user] = '1foo' + }.to raise_error(Puppet::Error, /Invalid username format for*/) + end + + it 'should accept user names with dashes' do + @gnupg_key[:user] = 'foo-bar' + end + + ['http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', 'ldap://keys.puppetlabs.com', 'hkp://pgp.mit.edu/'].each do |val| + it "should accept key_server #{val}" do + @gnupg_key[:key_server] = val + expect(@gnupg_key[:key_server]).to eq val.to_s + end + end + + ['puppet:///modules/gnupg/random.key', 'http://www.puppetlabs.com/key.key', 'https://www.puppetlabs.com/key.key', 'file:///etc/foo.key', '/etc/foo.key'].each do |val| + it "should accept key_source #{val}" do + @gnupg_key[:key_source] = val + expect(@gnupg_key[:key_source]).to eq val.to_s.gsub("file://", "") + end + end + + it "should not accept invalid formated key_source URI" do + expect { + @gnupg_key[:key_source] = 'httk://foo.bar/' + }.to raise_error(Puppet::Error) + end + + ['20BC0A86', 'D50582e6', '20BC0a86', '9B7D32F2D50582E6', '3CCe8BC520bc0A86'].each do |val| + it "should allow key_id with #{val}" do + @gnupg_key[:key_id] = val + expect(@gnupg_key[:key_id]).to eq val.upcase.intern + end + end + + ['ABCD', '1234567G', 'ASA1321', 'q321asd'].each do |val| + it "should not allow key_id with #{val}" do + expect { + @gnupg_key[:key_id] = val + }.to raise_error(/Invalid key id*/) + end + end + + [:public, :private, :both].each do |val| + it "should allow key_type with #{val}" do + @gnupg_key[:key_type] = val + expect(@gnupg_key[:key_type]).to eq val + end + end + + it "should have a key_type of public by default" do + expect(@gnupg_key[:key_type]).to eq :public + end + + [:special, :other].each do |val| + it "should not allow invalid key_type of #{val}" do + expect { + @gnupg_key[:key_type] = val + }.to raise_error(Puppet::Error) + end + end + + it "should not allow key_type of both when ensure is present" do + expect { + Puppet::Type.type(:gnupg_key).new(:name => "key", :ensure => 'present', :key_type => 'both', :key_source => "http://www.example.com") + }.to raise_error(/A key type of 'both' is invalid when ensure is 'present'\./) + end + + it "should allow key_content with armored public key" do + key = File.read('files/random.public.key') + resource = Puppet::Type.type(:gnupg_key).new(:name => "key", :key_type => 'public', :key_content => key) + expect(resource[:key_content]).to eq key + end + + it "should allow key_content with armored private key" do + key = File.read('files/random.private.key') + resource = Puppet::Type.type(:gnupg_key).new(:name => "key", :key_type => 'private', :key_content => key) + expect(resource[:key_content]).to eq key + end + + it "should not allow key_content that does not look like a public key when key_type is public" do + key = "I am not a public key" + expect { + Puppet::Type.type(:gnupg_key).new(:name => "key", :key_type => 'public', :key_content => key) + }.to raise_error(/Provided key content does not look like a public key\./) + end + + it "should not allow key_content that does not look like a private key when key_type is private" do + key = "I am not a private key" + expect { + Puppet::Type.type(:gnupg_key).new(:name => "key", :key_type => 'private', :key_content => key) + }.to raise_error(/Provided key content does not look like a private key\./) + end + +end diff --git a/tools/laptop_puppetisation/modules/gnupg/tests/gnupg_key.pp b/tools/laptop_puppetisation/modules/gnupg/tests/gnupg_key.pp new file mode 100644 index 00000000..a3b9a210 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/tests/gnupg_key.pp @@ -0,0 +1,40 @@ +gnupg_key { 'root_key_foo': + ensure => present, + user => 'root', + key_server => 'hkp://pgp.mit.edu/', + key_id => '20BC0A86', +} + +gnupg_key { 'jenkins_key': + ensure => present, + user => 'root', + key_id => 'D50582E6', + key_source => 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', +} + +gnupg_key {'root_remove': + ensure => absent, + key_id => D50582E6, + user => root, +} + +gnupg_key {'add_key_by_remote_source': + ensure => present, + key_id => F657C4B7, + user => root, + key_source => 'puppet:///modules/gnupg/random.key', +} + +gnupg_key {'add_key_by_local_source': + ensure => present, + key_id => F657C4B7, + user => root, + key_source => '/home/foo/public.key', +} + +gnupg_key {'add_key_by_local_source_file': + ensure => present, + key_id => F657C4B5, + user => root, + key_source => 'file:///home/foo/public.key', +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/gnupg/tests/init.pp b/tools/laptop_puppetisation/modules/gnupg/tests/init.pp new file mode 100644 index 00000000..12776287 --- /dev/null +++ b/tools/laptop_puppetisation/modules/gnupg/tests/init.pp @@ -0,0 +1 @@ +include gnupg diff --git a/tools/laptop_puppetisation/modules/homebrew/CHANGELOG.md b/tools/laptop_puppetisation/modules/homebrew/CHANGELOG.md new file mode 100644 index 00000000..87d2e75c --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/CHANGELOG.md @@ -0,0 +1,61 @@ +# CHANGELOG + +## 1.5.0 +- feature: allow package to set HOMEBREW_GITHUB_API_TOKEN +- feature/bugfix: stop parsing homebrew output, parse response codes instead +- bugfix: manage /usr/local/Homebrew rather than parent directory +- meta: speed up tests + +## 1.4.3 +- bugfix: manage objects (packages, taps, etc) case-insensitively +- meta: deprecate root-owned homebrew +- meta: clean up tests + +## 1.4.2 +- bugfix: fixed bug where brew-cask provider didn't work the first time +- meta: updated to new homebrew install location + +## 1.4.1 +- feature: allow usage by any member of homebrew group + +## 1.4.0 +- feature: remove files with invalid checksums for easier retrying +- bugfix: ensure `install_options` propgates correctly +- bugfix: detect and fail properly on checksum errors +- meta: include README section on ordering taps/packages + +## 1.3.3 +- feature: allow user/group override +- bugfix: remove `err` from facter code + +## 1.3.2 +- bugfix: fix compat issues for facter booleans +- bugfix: use puppet warning over ruby warn + +## 1.3.1 +- bugfix: only download CLI tools if values are set +- meta: move away from params class + +## 1.3.0 +- feature: allow users to manage taps +- meta: better testing, OSX-specific tests on Travis +- meta: fix typos, add contributer list + +## 1.2.0 +- bugfix: set directory permissions to brew defaults +- bugfix: fix brewcask parsing +- meta: enable auto-testing + +## 1.1.1 +- bugfix: ensure brew is called with correct user + +## 1.1.0 +- feature: add install_options +- feature: add upgradeable +- tech debt: clean up inheritance pattern + +## 1.0.1 +- documentation fixes + +## 1.0.0 +- initial release diff --git a/tools/laptop_puppetisation/modules/homebrew/Gemfile b/tools/laptop_puppetisation/modules/homebrew/Gemfile new file mode 100644 index 00000000..2a04b884 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +# syck removed from ruby 2, safe_yaml updated to fix this eventually, puppet~>3 uses older safe_yaml +gem 'safe_yaml', '>= 1.0.4' + +gem 'facter', '>= 1.7.0' +gem 'metadata-json-lint', '>= 0.0.11' +gem 'puppet', ENV.key?('PUPPET_VERSION') ? "#{ENV['PUPPET_VERSION']}" : ['>= 3.3'] +gem 'puppet-lint', '>= 1.1.0' diff --git a/tools/laptop_puppetisation/modules/homebrew/Gemfile-1.9.3 b/tools/laptop_puppetisation/modules/homebrew/Gemfile-1.9.3 new file mode 100644 index 00000000..8a7e0cdf --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/Gemfile-1.9.3 @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +# json and json_pure~>2 only compatible with ruby 2 +gem 'json', '~> 1.0' +gem 'json_pure', '~> 1.0' + +gem 'facter', '>= 1.7.0' +gem 'metadata-json-lint', '>= 0.0.11' +gem 'puppet', ENV.key?('PUPPET_VERSION') ? "#{ENV['PUPPET_VERSION']}" : ['>= 3.3'] +gem 'puppet-lint', '>= 1.1.0' diff --git a/tools/laptop_puppetisation/modules/homebrew/README.md b/tools/laptop_puppetisation/modules/homebrew/README.md new file mode 100644 index 00000000..762a3bfb --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/README.md @@ -0,0 +1,150 @@ +# puppet-homebrew + +A Puppet Module to install Homebrew and manage Homebrew packages on Mac OS X. +This module can install using either homebrew or brewcask, along with a +fallback mode which attempts both. + +puppet-homebrew is available on the +[Puppet Forge](https://forge.puppetlabs.com/thekevjames/homebrew). + +## Usage + +### Installing packages + +Use the Homebrew package provider like this: + +```puppet +class hightower::packages { + pkglist = ['postgresql', 'nginx', 'git', 'tmux'] + + package { $pkglist: + ensure => present, + provider => brew, + } +} +``` + +The providers works as follows: +* `provider => brew`: install using `brew install `. Do not use +brewcask. +* `provider => brewcask`: install using `brew cask install `. Only use +brewcask. +* `provider => homebrew`: attempt to install using `brew install `. On +failure, use `brew cask install ` + +### Tapping repositories + +To tap into new Github repositories, simply use the tap provider: + +```puppet +package { 'neovim/neovim': + ensure => present, + provider => tap, +} +``` + +You can untap a repository by setting ensure to `absent`. + +#### Ordering taps + +When both tapping a repo and installing a package from that repository, it is +important to make sure the former happens first. This can be accomplished in a +few different ways: either by doing so on a per-package basis: + +```puppet +package { 'neovim/neovim': + ensure => present, + provider => tap, +} -> +package { 'neovim': + ensure => present, + provider => homebrew, +} +``` + +or by setting all taps to occur before all other usages of this package with +[Resource Collectors](https://docs.puppet.com/puppet/latest/reference/lang_collectors.html): + +```puppet +# pick whichever provider(s) are relevant +Package <| provider == tap |> -> Package <| provider == homebrew |> +Package <| provider == tap |> -> Package <| provider == brew |> +Package <| provider == tap |> -> Package <| provider == brewcask |> +``` + +### Installing brew + +To install homebrew on a node (with a compiler already present!): + +```puppet +class { 'homebrew': + user => 'hightower', + group => 'developers', # defaults to 'admin' +} +``` + +As of late 2016, installing homebrew as the root user is deprecated, slated for +removal by brew maintainers in November 2016. It is highly recommended to +install brew as a standard (non-root) user. + +Note that some users have reported confusion between the *puppet* user and the +*homebrew* user -- it is perfectly fine to run puppet as root, in fact this is +encouraged, but the homebrew user should be non-root (generally, the system's +main user account). + +If you run puppet as a non-root user and set the `homebrew::user` to a +*different* non-root user, you may run into issues; namely, since this module +requires the puppet user act as the homebrew user, you may get a password +prompt on each run. This can be fixed by allowing the puppet user passwordless +sudo privileges to the homebrew user. + +To install homebrew and a compiler (on Lion or later), eg.: + +```puppet +class { 'homebrew': + user => 'kevin', + command_line_tools_package => 'command_line_tools_for_xcode_os_x_lion_april_2013.dmg', + command_line_tools_source => 'http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_lion_april_2013.dmg', +} +``` + +N.B. the author of this module does not maintain a mirror to command_line_tools. +You may need to search for a copy if you use this method. At the time of this +writing, downloading the command line tools sometimes requires an Apple ID. +Sorry, dude! + +#### Adding a Github Token + +Homebrew uses a Github token in your environment to make your experience better +by: + +- Reducing the rate limit on `brew search` commands +- Letting you tap your private repositories +- Allowing you to upload Gists of brew installation errors + +To enable this feature, you can include: + +```puppet +class { 'homebrew': + user => 'kevin', + github_token => 'MyT0k3n!', +} +``` + +Click +[here](https://github.com/settings/tokens/new?scopes=&description=Homebrew) to +create a personal access token for Github. + +## Original Author + +Original credit for this module goes to +[kelseyhightower](https://github.com/kelseyhightower). This module was forked +to provide brewcask integration. + +Credit for logic involved in tapping repositories goes to +[gildas](https://github.com/gildas/puppet-homebrew). + +## Contributers + +- Jordi Garcia +- Kevin James diff --git a/tools/laptop_puppetisation/modules/homebrew/checksums.json b/tools/laptop_puppetisation/modules/homebrew/checksums.json new file mode 100644 index 00000000..90580269 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/checksums.json @@ -0,0 +1,25 @@ +{ + "CHANGELOG.md": "c97e8726ef2505a032b5bd611a1b98df", + "Gemfile": "4e2b2fe37f4c8fe6a5874afba4d0341c", + "Gemfile-1.9.3": "34f06252b723938539191d2977824e8f", + "README.md": "902b7ee032300be416979b3406f89ce0", + "circle.yml": "d92be3f15232a14b43052cfd7a50d0fb", + "lib/facter/has_brew.rb": "cb8c27a6c69e375a1a5e0cd7b8d3d353", + "lib/facter/has_compiler.rb": "32865ee588128d3ea225cd738224eb87", + "lib/puppet/provider/package/brew.rb": "3bab5128d8993e778f91a1f31375ac85", + "lib/puppet/provider/package/brewcask.rb": "b2de44906411f38eb384c3cc46cd5652", + "lib/puppet/provider/package/brewcommon.rb": "924ddb1d3e0ceedc5c4f7d05ffe0a1fe", + "lib/puppet/provider/package/homebrew.rb": "dc496d979f4c0ce6d821379a43ade1b9", + "lib/puppet/provider/package/tap.rb": "eaab676ade67d8f1557e52c10b0b0ca3", + "manifests/compiler.pp": "c819679d797b9928b7326a342fc0e63d", + "manifests/init.pp": "7fe9802587e6843677989022630b8c98", + "manifests/install.pp": "30f4302578dd2bda4b9cdaf88e507856", + "metadata.json": "f80791d8c465938aa68b90e85687be06", + "test.sh": "e85c4eda84e03ff99685ca976034ac89", + "tests/init.pp": "77f62ffe2cab3725e8a6de0cde9a9b2f", + "tests/install_options.pp": "3376543613288dd5eda48584b755b8ee", + "tests/packages.pp": "997d251a37c83f555f82d488bae74381", + "tests/tap.pp": "abd78fda31dd47efb2268cfd3a73dbbf", + "tests/tap_priority.pp": "21d358f4ecf44bd1744fbea5ab51313c", + "tests/token.pp": "d76c1d4c7d28b22e1a2ea60bcac1421f" +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/homebrew/circle.yml b/tools/laptop_puppetisation/modules/homebrew/circle.yml new file mode 100644 index 00000000..911b9b2c --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/circle.yml @@ -0,0 +1,18 @@ +machine: + ruby: + version: 2.2.3 + +dependencies: + post: + - bundle exec puppet module build + - bundle exec puppet module install pkg/thekevjames-homebrew-*.tar.gz + +test: + override: + - STRICT_VARIABLES="yes" bundle exec puppet-lint --no-documentation-check --no-autoloader_layout-check --no-80chars-check manifests/init.pp + - STRICT_VARIABLES="yes" bundle exec puppet-lint --no-documentation-check --no-autoloader_layout-check --no-80chars-check manifests/install.pp + - STRICT_VARIABLES="yes" bundle exec puppet-lint --no-documentation-check --no-autoloader_layout-check --no-80chars-check manifests/compiler.pp + + - STRICT_VARIABLES="yes" bundle exec puppet parser validate --noop manifests/init.pp + - STRICT_VARIABLES="yes" bundle exec puppet parser validate --noop manifests/install.pp + - STRICT_VARIABLES="yes" bundle exec puppet parser validate --noop manifests/compiler.pp diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_brew.rb b/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_brew.rb new file mode 100644 index 00000000..c7f47843 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_brew.rb @@ -0,0 +1,12 @@ +Facter.add(:has_brew) do + setcode do + "nil" + end +end + +Facter.add(:has_brew) do + confine :operatingsystem => :darwin + setcode do + File.exists?('/usr/local/bin/brew') or system('brew --version >/dev/null 2>&1') ? "true" : "false" + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_compiler.rb b/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_compiler.rb new file mode 100644 index 00000000..8b31f8e1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/facter/has_compiler.rb @@ -0,0 +1,21 @@ +Facter.add(:has_compiler) do + setcode do + "nil" + end +end + +Facter.add(:has_compiler) do + confine :operatingsystem => :darwin + setcode do + File.exists?('/usr/bin/cc') or system('/usr/bin/xcrun -find cc >/dev/null 2>&1') ? "true" : "false" + end +end + +Facter.add(:has_compiler) do + # /usr/bin/cc exists in Mavericks, but it's not real + confine :operatingsystem => :darwin, :macosx_productversion_major => '10.9' + setcode do + (File.exists?('/Applications/Xcode.app') or File.exists?('/Library/Developer/CommandLineTools/')) and + (File.exists?('/usr/bin/cc') or system('/usr/bin/xcrun -find cc >/dev/null 2>&1')) ? "true" : "false" + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brew.rb b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brew.rb new file mode 100644 index 00000000..f87cb483 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brew.rb @@ -0,0 +1,84 @@ +Puppet::Type.type(:package).provide(:brew, + :parent => :brewcommon, + :source => :brewcommon) do + desc 'Package management using HomeBrew on OS X' + + has_feature :install_options + + def install + name = install_name + + begin + Puppet.debug "Looking for #{name} package..." + output = execute([command(:brew), :info, name], failonfail: true) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not find package: #{name}" + end + + begin + Puppet.debug "Package found, installing..." + output = execute([command(:brew), :install, name, *install_options], failonfail: true) + + if output =~ /sha256 checksum/ + Puppet.debug "Fixing checksum error..." + mismatched = output.match(/Already downloaded: (.*)/).captures + fix_checksum(mismatched) + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not install package: #{detail}" + end + + end + + def uninstall + name = @resource[:name].downcase + + Puppet.debug "Uninstalling #{name}" + execute([command(:brew), :uninstall, name]) + end + + def update + name = @resource[:name].downcase + + Puppet.debug "Upgrading #{name}" + execute([command(:brew), :upgrade, name]) + end + + def self.package_list(options={}) + Puppet.debug "Listing installed packages" + begin + if name = options[:justme] + result = execute([command(:brew), :list, '--versions', name]) + if result.empty? + Puppet.debug "Package #{result} not installed" + else + Puppet.debug "Found package #{result}" + end + else + result = execute([command(:brew), :list, '--versions']) + end + list = result.lines.map {|line| name_version_split(line)} + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not list packages: #{detail}" + end + + if options[:justme] + return list.shift + else + return list + end + end + + def self.name_version_split(line) + if line =~ (/^(\S+)\s+(.+)/) + { + :name => $1, + :ensure => $2, + :provider => :brew + } + else + Puppet.warning "Could not match #{line}" + nil + end + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcask.rb b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcask.rb new file mode 100644 index 00000000..6b48db5b --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcask.rb @@ -0,0 +1,82 @@ +Puppet::Type.type(:package).provide(:brewcask, + :parent => :brewcommon, + :source => :brewcommon) do + desc "Package management using HomeBrew casks on OS X" + + has_feature :install_options + + def install + name = install_name + + begin + Puppet.debug "Looking for #{name} package..." + output = execute([command(:brew), :cask, :info, name], failonfail: true) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not find package: #{name}" + end + + begin + Puppet.debug "Package found, installing..." + output = execute([command(:brew), :cask, :install, name, *install_options], failonfail: true) + if output =~ /sha256 checksum/ + Puppet.debug "Fixing checksum error..." + mismatched = output.match(/Already downloaded: (.*)/).captures + fix_checksum(mismatched) + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not install package: #{detail}" + end + end + + def uninstall + name = @resource[:name].downcase + + Puppet.debug "Uninstalling #{name}" + execute([command(:brew), :cask, :uninstall, name]) + end + + def update + name = @resource[:name].downcase + + Puppet.debug "Updating #{name}" + install + end + + def self.package_list(options={}) + Puppet.debug "Listing installed packages" + begin + if name = options[:justme] + result = execute([command(:brew), :cask, :list, '--versions', name]) + if result.empty? + Puppet.debug "Package #{result} not installed" + else + Puppet.debug "Found package #{result}" + end + else + result = execute([command(:brew), :list, '--versions']) + end + list = result.lines.map {|line| name_version_split(line)} + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not list packages: #{detail}" + end + + if options[:justme] + return list.shift + else + return list + end + end + + def self.name_version_split(line) + if line =~ (/^(\S+)\s+(.+)/) + { + :name => $1, + :ensure => $2, + :provider => :brewcask + } + else + Puppet.warning "Could not match #{line}" + nil + end + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcommon.rb b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcommon.rb new file mode 100644 index 00000000..76ca6753 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/brewcommon.rb @@ -0,0 +1,94 @@ +require 'puppet/provider/package' + +Puppet::Type.type(:package).provide(:brewcommon, + :parent => Puppet::Provider::Package) do + desc 'Base class for brew package management' + + confine :operatingsystem => :darwin + + # N.B. feature :install_options is not inheritable + has_feature :installable, :install_options + has_feature :uninstallable + has_feature :upgradeable + has_feature :versionable + + commands :brew => '/usr/local/bin/brew' + commands :stat => '/usr/bin/stat' + + def self.execute(cmd, failonfail = false, combine = false) + owner = stat('-nf', '%Uu', '/usr/local/bin/brew').to_i + group = stat('-nf', '%Ug', '/usr/local/bin/brew').to_i + home = Etc.getpwuid(owner).dir + + warn('Homebrew will be dropping support for root-owned homebrew by November 2016. Though this module will not prevent you from running homebrew as root, you may run into unexpected issues. Please migrate your installation to a user account -- this module will enforce this once homebrew has officially dropped support for root-owned installations.') if owner == 0 + + super(cmd, :uid => owner, :gid => group, :combine => combine, + :custom_environment => { 'HOME' => home }, :failonfail => failonfail) + end + + def execute(*args) + # This does not return exit codes in puppet <3.4.0 + # See https://projects.puppetlabs.com/issues/2538 + self.class.execute(*args) + end + + def install + raise Puppet::ExecutionFailure, 'Use brew provider.' + end + + def install_name + name = @resource[:name].downcase + should = @resource[:ensure].downcase + + case should + when true, false, Symbol + name + else + name + "-#{should}" + end + end + + def install_options + Array(resource[:install_options]).flatten.compact + end + + def uninstall + raise Puppet::ExecutionFailure, 'Use brew provider.' + end + + def update + raise Puppet::ExecutionFailure, 'Use brew provider.' + end + + def query + self.class.package_list(:justme => resource[:name].downcase) + end + + def latest + hash = self.class.package_list(:justme => resource[:name].downcase) + hash[:ensure] + end + + def self.package_list(options={}) + raise Puppet::ExecutionFailure, 'Use brew provider.' + end + + def self.name_version_split(line) + raise Puppet::ExecutionFailure, 'Use brew provider.' + end + + def self.instances(justme = false) + package_list.collect { |hash| new(hash) } + end + + def fix_checksum(files) + begin + for file in files + File.delete(file) + end + rescue Errno::ENOENT + Puppet.warning "Could not remove mismatched checksum files #{files}" + end + raise Puppet::ExecutionFailure, "Checksum error for package #{name} in files #{files}" + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/homebrew.rb b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/homebrew.rb new file mode 100644 index 00000000..9ab486eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/homebrew.rb @@ -0,0 +1,89 @@ +Puppet::Type.type(:package).provide(:homebrew, + :parent => :brewcommon, + :source => :brewcommon) do + desc 'Package management using HomeBrew (+ casks!) on OS X' + + has_feature :install_options + + def install + name = install_name + + begin + Puppet.debug "Looking for #{name} package on brew..." + output = execute([command(:brew), :info, name]) + if output.empty? + Puppet.debug "Package #{name} not found on Brew. Trying BrewCask..." + output = execute([command(:brew), :cask, :info, name], failonfail: true) + Puppet.debug "Package found on brewcask, installing..." + output = execute([command(:brew), :cask, :install, name, *install_options], failonfail: true) + else + Puppet.debug "Package found, installing..." + output = execute([command(:brew), :install, name, *install_options], failonfail: true) + if output =~ /sha256 checksum/ + Puppet.debug "Fixing checksum error..." + mismatched = output.match(/Already downloaded: (.*)/).captures + fix_checksum(mismatched) + end + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not install package: #{detail}" + end + end + + def uninstall + name = @resource[:name].downcase + + Puppet.debug "Uninstalling #{name}" + execute([command(:brew), :uninstall, name]) + execute([command(:brew), :cask, :uninstall, name]) + end + + def update + name = @resource[:name].downcase + + Puppet.debug "Updating #{name}" + install + end + + def self.package_list(options={}) + Puppet.debug "Listing installed packages" + begin + if name = options[:justme] + result = execute([command(:brew), :list, '--versions', name]) + unless result.include? name + result += execute([command(:brew), :cask, :list, '--versions', name]) + end + if result.empty? + Puppet.debug "Package #{result} not installed" + else + Puppet.debug "Found package #{result}" + end + else + result = execute([command(:brew), :list, '--versions']) + result += execute([command(:brew), :cask, :list, '--versions']) + end + list = result.lines.map {|line| name_version_split(line)} + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not list packages: #{detail}" + end + + if options[:justme] + return list.shift + else + return list + end + end + + def self.name_version_split(line) + if line =~ (/^(\S+)\s+(.+)/) + { + :name => $1, + :ensure => $2, + :provider => :homebrew + } + else + Puppet.warning "Could not match #{line}" + nil + end + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/tap.rb b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/tap.rb new file mode 100644 index 00000000..d17bb2b9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/lib/puppet/provider/package/tap.rb @@ -0,0 +1,64 @@ +Puppet::Type.type(:package).provide(:tap, + :parent => :brewcommon, + :source => :brewcommon) do + desc 'Tap management using HomeBrew on OS X' + + has_feature :install_options + + def install + name = @resource[:name].downcase + + Puppet.debug "Tapping #{name}" + output = execute([command(:brew), :tap, name, *install_options]) + + if output =~ /Error: Invalid tap name/ + raise Puppet::Error, "Could not find tap #{name}" + end + end + + def uninstall + name = @resource[:name].downcase + + Puppet.debug "Untapping #{name}" + execute([command(:brew), :untap, name]) + end + + def update + name = @resource[:name].downcase + + raise Puppet::Error, "Can not re-tap #{name}" + end + + def query + name = @resource[:name].downcase + + Puppet.debug "Querying tap #{name}" + begin + output = execute([command(:brew), :tap]) + output.each_line do |line| + line.chomp! + return { :name => line, :ensure => 'present', :provider => 'tap' } if line.downcase == name + end + rescue Puppet::ExecutionFailure => detail + Puppet.Err "Could not query tap: #{detail}" + end + nil + end + + def self.instances + Puppet.debug "Listing currently tapped repositories" + taps = [] + begin + output = execute([command(:brew), :tap]) + output.each_line do |line| + line.chomp! + next if line.empty? + taps << new({ :name => line, :ensure => 'present', :provider => 'tap' }) + end + taps + rescue Puppet::ExecutionFailure => detail + Puppet.Err "Could not list taps: #{detail}" + nil + end + end +end diff --git a/tools/laptop_puppetisation/modules/homebrew/manifests/compiler.pp b/tools/laptop_puppetisation/modules/homebrew/manifests/compiler.pp new file mode 100644 index 00000000..81817d00 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/manifests/compiler.pp @@ -0,0 +1,16 @@ +class homebrew::compiler { + + if $::has_compiler == "true" { + } elsif versioncmp($::macosx_productversion_major, '10.7') < 0 { + warning('Please install the Command Line Tools bundled with XCode manually!') + } elsif ($homebrew::command_line_tools_package and $homebrew::command_line_tools_source) { + + notice('Installing Command Line Tools.') + + package { $homebrew::command_line_tools_package: + ensure => present, + provider => pkgdmg, + source => $homebrew::command_line_tools_source, + } + } +} diff --git a/tools/laptop_puppetisation/modules/homebrew/manifests/init.pp b/tools/laptop_puppetisation/modules/homebrew/manifests/init.pp new file mode 100644 index 00000000..bf1132c9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/manifests/init.pp @@ -0,0 +1,30 @@ +class homebrew ( + $user, + $command_line_tools_package = undef, + $command_line_tools_source = undef, + $github_token = undef, + $group = 'admin' +) { + + if $::operatingsystem != 'Darwin' { + err('This Module works on Mac OS X only!') + fail('Exit') + } + + if $homebrew::user == 'root' { + warning('Homebrew will be dropping support for root-owned brew by November 2016. Though this module will not prevent you from installing homebrew as root, you may run into unexpected issues. It is highly recommended you follow brew guidelines (install as a non-root user) -- this module will enforce this once homebrew has officially dropped support for root-owned installations.') + } + + include homebrew::compiler + include homebrew::install + + if $homebrew::github_token { + file { '/etc/environment': ensure => present } -> + file_line { 'homebrew-github-api-token': + path => '/etc/environment', + line => "HOMEBREW_GITHUB_API_TOKEN=${homebrew::github_token}", + match => '^HOMEBREW_GITHUB_API_TOKEN', + } + } + +} diff --git a/tools/laptop_puppetisation/modules/homebrew/manifests/install.pp b/tools/laptop_puppetisation/modules/homebrew/manifests/install.pp new file mode 100644 index 00000000..06289db8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/manifests/install.pp @@ -0,0 +1,23 @@ +class homebrew::install { + + file { '/usr/local/Homebrew': + ensure => directory, + owner => $homebrew::user, + group => $homebrew::group, + mode => '0775', + recurse => true, + } -> + exec { 'install-homebrew': + cwd => '/usr/local', + command => "/usr/bin/su ${homebrew::user} -c '/bin/bash -o pipefail -c \"/usr/bin/curl -skSfL https://github.com/homebrew/brew/tarball/master | /usr/bin/tar xz -m --strip 1\"'", + creates => '/usr/local/bin/brew', + logoutput => on_failure, + timeout => 0, + } ~> + file { '/usr/local/bin/brew': + owner => $homebrew::user, + group => $homebrew::group, + mode => '0775', + } + +} diff --git a/tools/laptop_puppetisation/modules/homebrew/metadata.json b/tools/laptop_puppetisation/modules/homebrew/metadata.json new file mode 100644 index 00000000..9b692c61 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/metadata.json @@ -0,0 +1,25 @@ +{ + "name": "thekevjames-homebrew", + "version": "1.5.0", + "author": "thekevjames", + "summary": "Homebrew (+brewcask! +taps!) package installer and provider", + "license": "Apache-2.0", + "source": "https://github.com/TheKevJames/puppet-homebrew", + "project_page": "https://github.com/TheKevJames/puppet-homebrew", + "issues_url": "https://github.com/TheKevJames/puppet-homebrew/issues", + "dependencies": [ + {"name":"puppetlabs/stdlib","version_requirement":">= 4.2.0 < 5.0.0"} + ], + "data_provider": null, + "operatingsystem_support": [ + { + "operatingsystem": "Darwin" + } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">= 3.0.0 < 5.0.0" + } + ] +} diff --git a/tools/laptop_puppetisation/modules/homebrew/test.sh b/tools/laptop_puppetisation/modules/homebrew/test.sh new file mode 100755 index 00000000..00cfed75 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/test.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +FAILURES=0 + +apply() { + sudo BUNDLE_GEMFILE="$GEMFILE" FUTURE_PARSER="$FUTURE_PARSER" bundle exec puppet apply --detailed-exitcodes --debug "$@" || [ $? -eq 2 ] + FAILURES=$((FAILURES + $?)) +} +check() { + "$@" + FAILURES=$((FAILURES + $?)) +} + +if [ -n "$SLOW_TESTS" ]; then + if [ "$SLOW_TESTS" = "init.pp" ]; then + echo 'Apply init.pp...' + + echo -en 'travis_fold:start:script.test.init\\r' + apply tests/init.pp + check which brew + echo -en 'travis_fold:end:script.test.init\\r' + fi + + if [ "$SLOW_TESTS" = "token.pp" ]; then + echo 'Test apply token.pp...' + + echo -en 'travis_fold:start:script.test.token\\r' + apply tests/token.pp + check cat /etc/environment | grep HOMEBREW_GITHUB_API_TOKEN + echo -en 'travis_fold:end:script.test.token\\r' + fi +else + echo 'Apply install_options.pp...' + + echo -en 'travis_fold:start:script.test.install_options\\r' + apply tests/install_options.pp + check which ack + echo -en 'travis_fold:end:script.test.install_options\\r' + + + echo 'Apply packages.pp...' + + echo -en 'travis_fold:start:script.test.packages\\r' + apply tests/packages.pp + check stat /Applications/clementine.app/Contents/MacOS/clementine + check which git + check stat "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" + check which bzr + echo -en 'travis_fold:end:script.test.packages\\r' + + + echo 'Apply tap.pp...' + + echo -en 'travis_fold:start:script.test.tap\\r' + apply tests/tap.pp + check which gc2qif + echo -en 'travis_fold:end:script.test.tap\\r' + + + echo 'Apply tap_priority.pp...' + + echo -en 'travis_fold:start:script.test.tap_priority\\r' + apply tests/tap_priority.pp + check brew list ncl + echo -en 'travis_fold:end:script.test.tap_priority\\r' +fi + +if [ "$FAILURES" -ne "0" ]; then exit 1; fi diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/init.pp b/tools/laptop_puppetisation/modules/homebrew/tests/init.pp new file mode 100644 index 00000000..1fb887d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/init.pp @@ -0,0 +1,4 @@ +class { 'homebrew': + user => 'travis', + group => 'admin', +} diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/install_options.pp b/tools/laptop_puppetisation/modules/homebrew/tests/install_options.pp new file mode 100644 index 00000000..2fc1a36f --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/install_options.pp @@ -0,0 +1,7 @@ +package { 'ack': + ensure => latest, + provider => homebrew, + install_options => [ + '--with-default-names', + ], +} diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/packages.pp b/tools/laptop_puppetisation/modules/homebrew/tests/packages.pp new file mode 100644 index 00000000..925241e8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/packages.pp @@ -0,0 +1,19 @@ +package { 'git': # in brew + ensure => present, + provider => brew, +} + +package { 'bazaar': # in brew + ensure => present, + provider => homebrew, +} + +package { 'clementine': # in brewcask + ensure => present, + provider => homebrew, +} + +package { 'google-chrome': # in brewcask + ensure => present, + provider => brewcask, +} diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/tap.pp b/tools/laptop_puppetisation/modules/homebrew/tests/tap.pp new file mode 100644 index 00000000..180962d0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/tap.pp @@ -0,0 +1,13 @@ +package { 'meanbee/tap': + ensure => present, + provider => tap, +} -> +package { 'gc2qif': + ensure => present, + provider => homebrew, +} + +package { 'homebrew/versions': + ensure => absent, + provider => tap, +} diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/tap_priority.pp b/tools/laptop_puppetisation/modules/homebrew/tests/tap_priority.pp new file mode 100644 index 00000000..3eeb8c87 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/tap_priority.pp @@ -0,0 +1,11 @@ +Package <| provider == tap |> -> Package <| provider == homebrew |> + +package { 'homebrew/science': + ensure => present, + provider => tap, +} + +package { 'ncl': + ensure => present, + provider => homebrew, +} diff --git a/tools/laptop_puppetisation/modules/homebrew/tests/token.pp b/tools/laptop_puppetisation/modules/homebrew/tests/token.pp new file mode 100644 index 00000000..ca08a897 --- /dev/null +++ b/tools/laptop_puppetisation/modules/homebrew/tests/token.pp @@ -0,0 +1,5 @@ +class { 'homebrew': + user => 'travis', + group => 'admin', + github_token => 'test-token-not-valid', +} diff --git a/tools/laptop_puppetisation/modules/qahomebrew/manifests/init.pp b/tools/laptop_puppetisation/modules/qahomebrew/manifests/init.pp new file mode 100644 index 00000000..e78ebc60 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qahomebrew/manifests/init.pp @@ -0,0 +1,53 @@ +class qahomebrew ( + String $user = $mac_current_user, + String $group = 'staff' +) { + + require qaxcode + + #Lets sort out directory privilidges + $homebrew_directories = [ + '/usr/local/bin', + '/usr/local/etc', + '/usr/local/include', + '/usr/local/lib', + '/usr/local/lib/pkgconfig', + '/usr/local/Library', + '/usr/local/sbin', + '/usr/local/share', + '/usr/local/var', + '/usr/local/var/log', + '/usr/local/share/locale', + '/usr/local/share/man', + '/usr/local/share/man/man1', + '/usr/local/share/man/man2', + '/usr/local/share/man/man3', + '/usr/local/share/man/man4', + '/usr/local/share/man/man5', + '/usr/local/share/man/man6', + '/usr/local/share/man/man7', + '/usr/local/share/man/man8', + '/usr/local/share/info', + '/usr/local/share/doc', + '/usr/local/share/aclocal', + '/Library/Caches/Homebrew', + '/Library/Logs/Homebrew', + ] + + file {'/usr/local': + ensure => directory, + owner => $user, + group => $group, + mode => '0775', + } -> + file {$homebrew_directories: + ensure => directory, + owner => $user, + group => $group, + mode => '0775', + } -> + class { 'homebrew': + user => $user, + group => $group, + } +} diff --git a/tools/laptop_puppetisation/modules/qapackages/manifests/init.pp b/tools/laptop_puppetisation/modules/qapackages/manifests/init.pp new file mode 100644 index 00000000..f0024b68 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qapackages/manifests/init.pp @@ -0,0 +1,12 @@ +class qapackages { + require qahomebrew + #Following packages are installed via homebrew module + package {['git', 'tmux', 'gnupg']: + ensure => installed, + provider => brew + } + #Following packages are installed via software module + include software::browsers::chrome + include software::virtualization::virtualbox + +} diff --git a/tools/laptop_puppetisation/modules/qarubyecosystem/manifests/init.pp b/tools/laptop_puppetisation/modules/qarubyecosystem/manifests/init.pp new file mode 100644 index 00000000..7f177fda --- /dev/null +++ b/tools/laptop_puppetisation/modules/qarubyecosystem/manifests/init.pp @@ -0,0 +1,40 @@ +class qarubyecosystem ( + String $user = $mac_current_user +) { + require qahomebrew + + class { '::rvm':} + rvm::system_user { "$user": } + -> + #The installing of ruby via the rvm module uses brew as root which is no longer + #supported, hence we use exec for the installation of ruby + exec { 'install_ruby.2.3': + timeout => 0, + require => Class['::rvm'], + command => "sudo -u $user rvm install ruby-2.3", + unless => "sudo -u $user rvm list | grep 2.3", + path => ['/bin','/usr/sbin/','/usr/bin/','/usr/local/rvm/bin/'], + } -> + exec { 'default_ruby.2.3': + command => "sudo -u $user rvm alias create default ruby-2.3@qadefault", + path => ['/bin','/usr/sbin/','/usr/bin/', '/usr/local/rvm/bin/'], + unless => "sudo -u $user rvm list | grep '* ruby-2.3'", + } -> + rvm_gemset { + 'ruby-2.3@qadefault': + ensure => present, + } -> + rvm_gem { + 'ruby-2.3@qadefault/bundler': + ensure => '1.12.5', + } -> + rvm_gem { + 'ruby-2.3@qadefault/vmfloaty': + ensure => '0.7.7', + } -> + exec { 'default_ruby-2.3_qa_gemset': + command => "sudo -u $user rvm use gemset ruby-2.3.0@qadefault --default", + path => ['/bin','/usr/sbin/','/usr/bin/', '/usr/local/rvm/bin/'], + unless => "sudo -u $user rvm list gemsets | grep '> ruby-2.3.0@qadefault'", + } +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/qavmpoolerbitbar/manifests/init.pp b/tools/laptop_puppetisation/modules/qavmpoolerbitbar/manifests/init.pp new file mode 100755 index 00000000..55d642d1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qavmpoolerbitbar/manifests/init.pp @@ -0,0 +1,37 @@ +class qavmpoolerbitbar ( + String $user = $mac_current_user, + String $group = 'staff' +) { + require qahomebrew + require qapackages + + package { ['bitbar']: + ensure => present, + provider => homebrew, + } -> file { "/Users/$user/repos": + ensure => directory, + owner => $user, + group => $group + } -> + vcsrepo { "/Users/$user/repos/vmpooler-bitbar": + ensure => present, + provider => git, + source => "https://github.com/seamymckenna/vmpooler-bitbar", + } -> + file { "/Users/$user/plugins": + ensure => directory, + owner => $user, + group => $group + } -> + exec { 'config_bit_bar_plugins_folder': + path => ['/bin','/usr/sbin/','/usr/bin/'], + command => "defaults write /Applications/BitBar.app pluginsDirectory /Users/$user/plugins", + unless => "ls /Users/$user/repos/vmpooler-bitbar/ | grep vmpooler-bitbar.30s.rb" + } -> + file { "/Users/$user/plugins/vmpooler-bitbar.30s.rb": + ensure => 'link', + target => "/Users/$user/repos/vmpooler-bitbar/vmpooler-bitbar.30s.rb", + owner => $user, + group => $group + } +} diff --git a/tools/laptop_puppetisation/modules/qaxcode/examples/init.pp b/tools/laptop_puppetisation/modules/qaxcode/examples/init.pp new file mode 100644 index 00000000..42377809 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qaxcode/examples/init.pp @@ -0,0 +1 @@ +include 'qa_xcode' diff --git a/tools/laptop_puppetisation/modules/qaxcode/files/install_xcode_cli_tools.sh b/tools/laptop_puppetisation/modules/qaxcode/files/install_xcode_cli_tools.sh new file mode 100644 index 00000000..1e76e239 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qaxcode/files/install_xcode_cli_tools.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Get and install Xcode CLI tools +# create the placeholder file that's checked by CLI updates' .dist code +# in Apple's SUS catalog +touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress +# find the CLI Tools update +PROD=$(softwareupdate -l | grep "\*.*Command Line" | head -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | tr -d '\n') +# install it +softwareupdate -i "$PROD" --verbose +rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress diff --git a/tools/laptop_puppetisation/modules/qaxcode/manifests/init.pp b/tools/laptop_puppetisation/modules/qaxcode/manifests/init.pp new file mode 100644 index 00000000..0286d8a6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/qaxcode/manifests/init.pp @@ -0,0 +1,25 @@ +class qaxcode ( + String $user = $mac_current_user, + String $group = 'admin' +) { + #Create a scripts directory + file {"/Users/$user/scripts": + ensure => directory, + owner => $user, + group => $group, + }-> + #Create the install script + file {"/Users/$user/scripts/install_xcode_cli_tools.sh": + ensure => present, + owner => $user, + group => $group, + source => "puppet:///modules/qaxcode/install_xcode_cli_tools.sh", + mode => '0755', + } -> + exec { 'install_xcode_cli_tools': + path => ['/Users/$user/scripts','/usr/sbin/','/usr/bin/','/bin/'], + command => "/Users/$user/scripts/install_xcode_cli_tools.sh", + creates => '/Library/Developer/CommandLineTools/', + timeout => 600 + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/Gemfile b/tools/laptop_puppetisation/modules/rvm/Gemfile new file mode 100644 index 00000000..e65e84b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/Gemfile @@ -0,0 +1,17 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +source 'https://rubygems.org' + +gem 'puppet', ENV['PUPPET_VERSION'] || '>= 3.0', :require => false + +gem 'rake', :require => false +gem 'rspec-puppet', '>= 2.1.0', :require => false +gem 'puppetlabs_spec_helper', '>= 0.8.0', :require => false +gem 'puppet-lint', '>= 1.1.0', :require => false +gem 'simplecov', :require => false +gem 'puppet-blacksmith', '>= 3.3.1', :require => false +gem 'librarian-puppet', '>= 2.0.0', :require => false +gem 'beaker-rspec', '>= 3.0.0', :require => false + +# vim:ft=ruby diff --git a/tools/laptop_puppetisation/modules/rvm/LICENSE b/tools/laptop_puppetisation/modules/rvm/LICENSE new file mode 100644 index 00000000..61975f87 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2012-2013, MaestroDev, Brandon Turner +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Brandon Turner nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BRANDON TURNER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tools/laptop_puppetisation/modules/rvm/README.markdown b/tools/laptop_puppetisation/modules/rvm/README.markdown new file mode 100644 index 00000000..24015f5e --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/README.markdown @@ -0,0 +1,282 @@ +Puppet Module for Ruby Version Manager (RVM) +============================================== + +[![Build Status](https://travis-ci.org/maestrodev/puppet-rvm.svg?branch=maestrodev)](https://travis-ci.org/maestrodev/puppet-rvm) +[![Puppet Forge](https://img.shields.io/puppetforge/v/maestrodev/rvm.svg)](https://forge.puppetlabs.com/maestrodev/rvm) +[![Puppet Forge](https://img.shields.io/puppetforge/f/maestrodev/rvm.svg)](https://forge.puppetlabs.com/maestrodev/rvm) + +This module handles installing system RVM (also known as multi-user installation +as root) and using it to install rubies and gems. Support for installing and +configuring passenger is also included. + +We are actively using this module. It works well, but does have some issues you +should be aware of. Due to the way puppet works, certain resources +(rvm\_sytem\_ruby, rvm\_gem and rvm\_gemset) may generate errors until RVM is +installed. You may want to use run stages to install RVM before the rest +of your configuration runs. However, if you run puppet using the `--noop` +parameter, you may see _Could not find a default provider_ errors. See the +Troubleshooting section for more information. + +Please read the troubleshooting section below before opening an issue. + + +## System Requirements + +Puppet 3.0.0 or higher. + +## Upgrading + +* 1.12: uses [golja-gnupg](https://forge.puppetlabs.com/golja/gnupg) module +to manage the installation of the gpg key. +* 1.5: no longer includes a dependency on puppetlabs/apache, you must install it yourself +if you want to use the passenger module. + +## Add Puppet Module + +Before you begin, you must add the RVM module to your Puppet installation. This can be done with: + + $ puppet module install maestrodev/rvm + +You may now continue configuring RVM resources. + + +## Install RVM with Puppet + + class { '::rvm': } + +This will install RVM into `/usr/local/rvm`. + +To use RVM without sudo, users need to be added to the `rvm` group. This can be easily done with: + + rvm::system_user { bturner: ; jdoe: ; jsmith: ; } + +If GPG is installed, installing RVM requires the RVM GPG key. +This module will install the key if `gpg` is already installed or being installed with the +[`golja-gnupg`](https://forge.puppetlabs.com/golja/gnupg) module. + +If you don't want this module to install the gpg key just set to false the `gpg_key_id` parameter + + class { '::rvm': gnupg_key_id => false } + +## Installing Ruby + +You can tell RVM to install one or more Ruby versions with: + + rvm_system_ruby { + 'ruby-1.9': + ensure => 'present', + default_use => true, + build_opts => ['--binary']; + 'ruby-2.0': + ensure => 'present', + default_use => false; + } + +You should use the full version number. While the shorthand version may work (e.g. '1.9.2'), the provider will be unable to detect if the correct version is installed. + +If rvm fails to install binary rubies you can increase curl's timeout with the `rvm_max_time_flag` in `~/.rvmrc` with a fully qualified path to the home directory. + + # ensure rvm doesn't timeout finding binary rubies + # the umask line is the default content when installing rvm if file does not exist + file { '/home/user/rvmrc': + content => 'umask u=rwx,g=rwx,o=rx + export rvm_max_time_flag=20', + mode => '0664', + before => Class['rvm'], + } + +Or, to configure `/etc/rvmrc` you can use use `Class['rvm::rvmrc]` + + class{ 'rvm::rvmrc': + max_time_flag => 20, + before => Class['rvm'], + } + +### Installing JRuby from sources + +JRuby has some extra requirements, java, maven and ant that you can install using +[puppetlabs/java](http://forge.puppetlabs.com/puppetlabs/java), +[maestrodev/ant](http://forge.puppetlabs.com/maestrodev/ant) and +[maestrodev/maven](http://forge.puppetlabs.com/maestrodev/maven) modules. + + class { 'java': } -> + class { 'ant': } -> + class { 'maven::maven': } -> + rvm_system_ruby { 'jruby-1.7.6': + ensure => 'present', + default_use => false; + } + + +## Creating Gemsets + +Create a gemset with: + + rvm_gemset { + 'ruby-1.9.3-p448@myproject': + ensure => present, + require => Rvm_system_ruby['ruby-1.9.3-p448']; + } + + +## Installing Gems + +Install a gem with: + + rvm_gem { + 'ruby-1.9.3-p448@myproject/bundler': + ensure => '1.0.21', + require => Rvm_gemset['ruby-1.9.3-p448@myproject']; + } + +The *name* of the gem should be `[@]/`. For example, you can install bundler for ruby-1.9.2 using `ruby-1.9.3-p448/bundler`. You could install rails in your project's gemset with: `ruby-1.9.3-p448@myproject/rails`. + +Alternatively, you can use this more verbose syntax: + + rvm_gem { + 'bundler': + name => 'bundler', + ruby_version => 'ruby-1.9.3-p448', + ensure => latest, + require => Rvm_system_ruby['ruby-1.9.3-p448']; + } + +## Creating Aliases + +To create an RVM alias, you can use: + + rvm_alias { + 'myproject': + target_ruby => 'ruby-1.9.3-p448@myproject', + ensure => present, + require => Rvm_gemset['ruby-1.9.3-p448@myproject']; + } + +## Creating Wrappers + +To create an RVM wrapper, you can use: + + rvm_wrapper { + 'god': + target_ruby => 'ruby-1.9.3-p448', + prefix => 'bootup', + ensure => present, + require => Rvm_system_ruby['ruby-1.9.3-p448']; + } + +## Installing Passenger + +NOTE: You must install the [puppetlabs/apache](http://forge.puppetlabs.com/puppetlabs/apache) module by yourself. +It is not included as a dependency to this module to avoid installing it when is not needed most times. + +Install passenger using the [puppetlabs/apache](http://forge.puppetlabs.com/puppetlabs/apache) module, +and using: + + class { 'apache': } + class { 'rvm::passenger::apache': + version => '3.0.11', + ruby_version => 'ruby-1.9.3-p448', + mininstances => '3', + maxinstancesperapp => '0', + maxpoolsize => '30', + spawnmethod => 'smart-lv2', + } + +## Using Hiera + +You can configure the ruby versions to be installed and the system users from hiera + + rvm::system_rubies: + 'ruby-1.9': + default_use: true + 'ruby-2.0': {} + 'jruby-1.7': {} + + rvm::system_users: + - john + - doe + + rvm::rvm_gems: + 'bundler': + name: 'bundler' + ruby_version: 'ruby-1.9' + ensure: latest + + +## Building the module + +Testing is done with rspec, [Beaker-rspec](https://github.com/puppetlabs/beaker-rspec), [Beaker](https://github.com/puppetlabs/beaker)) + +To test and build the module + + bundle install + # run specs + rake + + # run Beaker system tests with vagrant vms + rake beaker + # to use other vm from the list spec/acceptance/nodesets and not destroy the vm after the tests + BEAKER_destroy=no BEAKER_set=centos-64-x64 bundle exec rake beaker + + # Release the Puppet module to the Forge, doing a clean, build, tag, push, bump_commit and git push + rake module:release + +## Troubleshooting / FAQ + +### An error "Could not find a default provider for rvm\_system\_ruby" is displayed when running Puppet with --noop + +This means that puppet cannot find the `/usr/local/rvm/bin/rvm` command +(probably because RVM isn't installed yet). Currently, Puppet does not support +making a provider suitable using another resource (late-binding). You may want +to use run stages to install RVM before the rest of the +configuration runs. When running in _noop_ mode, RVM is not actually installed +causing rvm\_system\_ruby, rvm\_gem and rvm\_gemset resources to generate this +error. You can avoid this error by surrounding your rvm configuration in an if +block: + + if $rvm_installed == "true" { + rvm_system_ruby ... + } + +Do not surround `include rvm` in the if block, as this is used to install RVM. + +NOTE: $rvm\_installed is evaluated at the beginning of each puppet run. If you +use this in your manifests, you will need to run puppet twice to fully +configure RVM. + +### An error "Resource type rvm_gem does not support parameter false" prevents puppet from running. + +The RVM module requires Puppet version 2.6.7 or higher. + +There is a bug in Puppet versions 2.7.4 through 2.7.9 that also causes this +error. The error can be safely ignored in these versions. For best results, +upgrade to Puppet 2.7.10. + + +### Some packages/libraries I don't want or need are installed (e.g. build-essential, libc6-dev, libxml2-dev). + +RVM works by compiling Ruby from source. This means you must have all the libraries and binaries required to compile Ruby installed on your system, which is handled by rvm autolibs in newer versions of RVM. + + +### It doesn't work on my operating system. + +Check the rspec-system tests as described above to test in a specific OS +If that doesn't work feel free to send a pull request ;) + + +### Why didn't you just add an RVM provider for the existing package type? + +The puppet [package](http://docs.puppetlabs.com/references/latest/type.html#package) +type seems like an obvious place for the RVM provider. It would be nice if the syntax +for installing Ruby with RVM looked like: + + # NOTE: This does not work + package {'ruby': + provider => 'rvm', + ensure => '1.9.2-p290'; + } + +While this may be possible, it becomes harder to manage multiple Ruby versions and +nearly impossible to install gems for a specific Ruby version. For this reason, +I decided it was best to create a completely new set of types for RVM. + diff --git a/tools/laptop_puppetisation/modules/rvm/Rakefile b/tools/laptop_puppetisation/modules/rvm/Rakefile new file mode 100644 index 00000000..466d7a1c --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/Rakefile @@ -0,0 +1,31 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +require 'rake/clean' +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppet_blacksmith/rake_tasks' + +CLEAN.include('spec/fixtures/manifests/', 'spec/fixtures/modules/', 'doc', 'pkg') +CLOBBER.include('.tmp', '.librarian') + + +task :librarian_spec_prep do + sh "librarian-puppet install --path=spec/fixtures/modules/" +end +task :spec_prep => :librarian_spec_prep + +Rake::Task[:lint].clear # workaround https://github.com/rodjek/puppet-lint/issues/331 +PuppetLint.configuration.relative = true # https://github.com/rodjek/puppet-lint/pull/334 +PuppetLint::RakeTask.new :lint do |config| + config.pattern = 'manifests/**/*.pp' + config.disable_checks = ["80chars", "class_inherits_from_params_class"] + config.fail_on_warnings = true + # config.relative = true +end + +Blacksmith::RakeTask.new do |t| + t.build = false # do not build the module nor push it to the Forge, just do the tagging [:clean, :tag, :bump_commit] +end + +task :default => [:clean, :validate, :lint, :spec] diff --git a/tools/laptop_puppetisation/modules/rvm/checksums.json b/tools/laptop_puppetisation/modules/rvm/checksums.json new file mode 100644 index 00000000..73f5e696 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/checksums.json @@ -0,0 +1,65 @@ +{ + "Gemfile": "a8b077ddeb33c19277f272d9bf9d3151", + "Gemfile.lock": "d6a35a0e7f1e9fa546d9e01d06363c71", + "LICENSE": "c09f1ff12ffc19bb5aa3ca918d6496c7", + "Puppetfile.lock": "5a77b85e530c4b42b37fadbe6789f1e8", + "README.markdown": "264d8d2d206934390fb42fcafdf3ae14", + "Rakefile": "78ea614b4262234dc92489017f039d27", + "lib/facter/rvm_installed.rb": "17880333546300f31ee0b924dc0e7135", + "lib/facter/rvm_version.rb": "83ce2d25f399adbcbc04c9f441066c8b", + "lib/puppet/provider/rvm_alias/alias.rb": "7f422f68856ffa399a7d564fc7cdc62e", + "lib/puppet/provider/rvm_gem/gem.rb": "c2d8e583224acdb26560a90d6c56fd5c", + "lib/puppet/provider/rvm_gemset/gemset.rb": "a7636d1c484444c64c1aad1be2c2d30a", + "lib/puppet/provider/rvm_system_ruby/rvm_system_ruby.rb": "1cd383745b30dacb637f156c924bb961", + "lib/puppet/provider/rvm_wrapper/wrapper.rb": "238ba3f4d28a019952a99bbdde35f675", + "lib/puppet/type/rvm_alias.rb": "33c703a7c346235f0dba87de1a43a859", + "lib/puppet/type/rvm_gem.rb": "12454b731120e995452d9402d1d7d9d3", + "lib/puppet/type/rvm_gemset.rb": "9f7d37bc51c2b75a288ea4edca5f57a8", + "lib/puppet/type/rvm_system_ruby.rb": "4161ea449b25c63a085f63399b7c2415", + "lib/puppet/type/rvm_wrapper.rb": "4e85d8d1c7bae4a7549e7f0edbcbc4df", + "manifests/dependencies/centos.pp": "4128b515beeb93a6ab5905452e467d83", + "manifests/dependencies/oraclelinux.pp": "3f60f61da00a2e41109058fe70ed7536", + "manifests/dependencies/ubuntu.pp": "c18938a26d927f3c4f3a64bddd3b1948", + "manifests/dependencies.pp": "421d1b11cb1395ee0d2f3763e75d8c72", + "manifests/gnupg_key.pp": "62b190beebda0b14e78d031c6622e4fc", + "manifests/gpg.pp": "eb3ed96b79c9b95a3f56a3f59ed106da", + "manifests/group.pp": "285626ffd33373de2fec6ebc66d6c71d", + "manifests/init.pp": "8af3586436f9c70bb8296c452c3674e9", + "manifests/params.pp": "cd383eebc57525ec9422ebb64b5dc48d", + "manifests/passenger/apache.pp": "2df4eb774a759493c54cd15ad54a21fd", + "manifests/passenger/dependencies/centos.pp": "11c1f59ccdc4cead38a9fa550bb03812", + "manifests/passenger/dependencies/oraclelinux.pp": "388ca20676c972d2a85790374adae45f", + "manifests/passenger/dependencies/ubuntu.pp": "1a61e3cb072c82f68d8ff604f1e59e47", + "manifests/passenger/dependencies.pp": "e819338156ed5965ebdbc76f6b698a75", + "manifests/passenger/gem.pp": "80587f1bc2beab8b91f3b54932e60e7c", + "manifests/rvmrc.pp": "96bc8d0edd1cfdb69a5a7e154ae66573", + "manifests/system.pp": "5921861bf58f6c53d8284a0d288a1709", + "manifests/system_user.pp": "145def8820dd6c823f838910434ab54e", + "metadata.json": "aabe6db6554a0609a3b6541f76d7e1e8", + "spec/acceptance/nodesets/centos-65-x64-docker.yml": "9674bdbae4ed3135a8567b5f7a3105ff", + "spec/acceptance/nodesets/centos-65-x64.yml": "93493768080a4d0f2d04ef7d75b717a5", + "spec/acceptance/nodesets/debian-7-x64-docker.yml": "3b89e3555ba378b350ff898de2bed74a", + "spec/acceptance/nodesets/debian-7-x64.yml": "49a054626b92ba240aa09c2fac824a73", + "spec/acceptance/nodesets/debian-73-x64.yml": "d93ed0079254ebb6a603d829acea77ef", + "spec/acceptance/nodesets/default.yml": "9674bdbae4ed3135a8567b5f7a3105ff", + "spec/acceptance/nodesets/ubuntu-server-1404-x64-docker.yml": "452fa39e36c94494eee5a4a602a918f5", + "spec/acceptance/nodesets/ubuntu-server-1404-x64.yml": "ec5f2ace9479ea9c625ef8764b6c2557", + "spec/acceptance/rvm_system_spec.rb": "2aee82eb49bd0117b9ace79ce0de4a17", + "spec/classes/dependencies_spec.rb": "d40ac9bd6ce9b4bf96d8fc2ce5740b6c", + "spec/classes/gnupg_key_spec.rb": "f8ac907a4829208a07dffb17082724d5", + "spec/classes/gpg_spec.rb": "d8ed63bf7c3d833dc299e8137a25a5b2", + "spec/classes/init_spec.rb": "60a932fc8bd097227f03a591bb933157", + "spec/classes/rvmrc_spec.rb": "8a89f89ca9b7b9ec1d5c9bc2868be646", + "spec/classes/system_spec.rb": "571417ace6bd69cc3ef81a1ee1b2b268", + "spec/defines/rvm_alias_spec.rb": "83c263ca60fd32aec9fbccc8f3679e83", + "spec/defines/rvm_gem_spec.rb": "c26c78f19676b8a03e96bd30625ab2fb", + "spec/defines/rvm_gemset_spec.rb": "ae6518149a7100a1f35a80a919b1f55f", + "spec/defines/rvm_system_ruby_spec.rb": "328be8c8810d2a9acf8b8f4799cefc33", + "spec/defines/rvm_wrapper_spec.rb": "a37c75e48716ce92e2ad5381c821397f", + "spec/defines/system_user_spec.rb": "ad388253a17f0eba6bb906ca6d3f1715", + "spec/fixtures/hiera.yaml": "37ca9bf76ec6d6a251fdcc6c559a3619", + "spec/spec_helper.rb": "3ce7855a3a830837a3c338b33cf38baa", + "spec/spec_helper_acceptance.rb": "2899ac6512eea19a0b09fe68c123ac1f", + "templates/rvmrc.erb": "3e6e47c115ed6136278c476b090bcada", + "tests/init.pp": "7096c96ab9b56ee1dab6e2b5754e770a" +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_installed.rb b/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_installed.rb new file mode 100644 index 00000000..411afd5e --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_installed.rb @@ -0,0 +1,7 @@ +Facter.add("rvm_installed") do + rvm_binary = "/usr/local/rvm/bin/rvm" + + setcode do + File.exists? rvm_binary + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_version.rb b/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_version.rb new file mode 100644 index 00000000..23446ab7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/facter/rvm_version.rb @@ -0,0 +1,7 @@ +Facter.add("rvm_version") do + rvm_binary = "/usr/local/rvm/bin/rvm" + + setcode do + File.exists?(rvm_binary) ? `#{rvm_binary} version`.strip.match(/rvm ([0-9]+\.[0-9]+\.[0-9]+) .*/)[1] : nil + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_alias/alias.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_alias/alias.rb new file mode 100644 index 00000000..253adb54 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_alias/alias.rb @@ -0,0 +1,46 @@ +# RVM gemset support +Puppet::Type.type(:rvm_alias).provide(:alias) do + desc "RVM alias support." + + has_command(:rvmcmd, '/usr/local/rvm/bin/rvm') do + environment :HOME => ENV['HOME'] + end + + def target_ruby + resource[:target_ruby] + end + + def alias_name + resource[:name] + end + + def aliascmd + [command(:rvmcmd), "alias"] + end + + def alias_list + command = aliascmd + ['list'] + + list = [] + begin + list = execute(command) + rescue Puppet::ExecutionFailure => detail + end + + list.to_s + end + + def create + command = aliascmd + ['create', alias_name, target_ruby] + execute(command) + end + + def destroy + command = aliascmd + ['delete', alias_name] + execute(command) + end + + def exists? + alias_list.match("#{alias_name} => #{target_ruby}") + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gem/gem.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gem/gem.rb new file mode 100644 index 00000000..704c20b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gem/gem.rb @@ -0,0 +1,144 @@ +require 'puppet/provider/package' +require 'uri' + +# Ruby gems support. +Puppet::Type.type(:rvm_gem).provide(:gem) do + desc "Ruby Gem support using RVM." + + has_feature :versionable + has_command(:rvmcmd, '/usr/local/rvm/bin/rvm') do + environment :HOME => ENV['HOME'] + end + + + def ruby_version + resource[:ruby_version] + end + + def gembinary + [command(:rvmcmd), ruby_version, "do", "gem"] + end + + + def gemlist(hash) + command = gembinary + ['list'] + + if hash[:local] + command << "--local" + else + command << "--remote" + end + + if name = hash[:justme] + command << '^' + name + '$' + end + + # use proxy if proxy_url is set + if resource[:proxy_url] and !resource[:proxy_url].empty? + command << "--http-proxy" << resource[:proxy_url] + end + + list = [] + begin + list = execute(command).split("\n").collect do |set| + if gemhash = self.class.gemsplit(set) + gemhash[:provider] = :gem + gemhash + else + nil + end + end.compact + rescue Puppet::ExecutionFailure => detail + end + + if hash[:justme] + return list.shift + else + return list + end + end + + def self.gemsplit(desc) + case desc + when /^\*\*\*/, /^\s*$/, /^\s+/; return nil + when /gem: not found/; return nil + # when /^(\S+)\s+\((((((\d+[.]?))+)(,\s)*)+)\)/ + when /^(\S+)\s+\((\d+.*)\)/ + name = $1 + version = $2.split(/,\s*/) + return { + :name => name, + :ensure => version + } + else + Puppet.warning "Could not match #{desc}" + nil + end + end + + + def install(useversion = true) + command = gembinary + ['install'] + command << "-v" << resource[:ensure] if (! resource[:ensure].is_a? Symbol) and useversion + # Dependencies are now installed by default + # command << "--include-dependencies" + + # use proxy if proxy_url is set + if resource[:proxy_url] and !resource[:proxy_url].empty? + command << "--http-proxy" << resource[:proxy_url] + end + + if source = resource[:source] + begin + uri = URI.parse(source) + rescue => detail + fail "Invalid source '#{uri}': #{detail}" + end + + case uri.scheme + when nil + # no URI scheme => interpret the source as a local file + command << source + when /file/i + command << uri.path + when 'puppet' + # we don't support puppet:// URLs (yet) + raise Puppet::Error.new("puppet:// URLs are not supported as gem sources") + else + # interpret it as a gem repository + command << "--source" << "#{source}" << resource[:name] + end + else + command << "--no-rdoc" << "--no-ri" << resource[:name] + end + + # makefile opts, + # must be last + if resource[:withopts] + command << "--" << resource[:withopts] + end + + output = execute(command) + # Apparently some stupid gem versions don't exit non-0 on failure + self.fail "Could not install: #{output.chomp}" if output.include?("ERROR") + end + + def latest + # This always gets the latest version available. + hash = gemlist(:justme => resource[:name]) + + hash[:ensure][0] + end + + def query + gemlist(:justme => resource[:name], :local => true) + end + + def uninstall + execute(gembinary + ["uninstall", "-x", "-a", resource[:name]]) + end + + def update + self.install(false) + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gemset/gemset.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gemset/gemset.rb new file mode 100644 index 00000000..0e571669 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_gemset/gemset.rb @@ -0,0 +1,57 @@ +# RVM gemset support +Puppet::Type.type(:rvm_gemset).provide(:gemset) do + desc "RVM gemset support." + + has_command(:rvmcmd, '/usr/local/rvm/bin/rvm') do + environment :HOME => ENV['HOME'] + end + + def ruby_version + resource[:ruby_version] + end + + def gemset_name + resource[:name] + end + + def gemsetcommand + [command(:rvmcmd), ruby_version, "exec", "rvm", "gemset"] + end + + def gemsetcommand_force + [command(:rvmcmd), ruby_version, "exec", "rvm", "--force", "gemset"] + end + + def gemset_list + command = gemsetcommand + ['list'] + + # use proxy if proxy_url is set + if resource[:proxy_url] and !resource[:proxy_url].empty? + command << "--http-proxy" << resource[:proxy_url] + end + + list = [] + begin + list = execute(command).split("\n").collect do |line| + line.strip if line =~ /^\s+\S+/ + end.compact + rescue Puppet::ExecutionFailure => detail + end + + list + end + + def create + command = gemsetcommand + ['create', gemset_name] + execute(command) + end + + def destroy + command = gemsetcommand_force + ['delete', gemset_name] + execute(command) + end + + def exists? + gemset_list.include? gemset_name + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_system_ruby/rvm_system_ruby.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_system_ruby/rvm_system_ruby.rb new file mode 100644 index 00000000..8846ac55 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_system_ruby/rvm_system_ruby.rb @@ -0,0 +1,66 @@ +Puppet::Type.type(:rvm_system_ruby).provide(:rvm) do + desc "Ruby RVM support." + + has_command(:rvmcmd, '/usr/local/rvm/bin/rvm') do + environment :HOME => ENV['HOME'] + end + + def create + unless resource[:proxy_url].nil? + ENV['http_proxy'] = resource[:proxy_url] + ENV['https_proxy'] = resource[:proxy_url] + unless resource[:no_proxy].nil? + ENV['no_proxy'] = resource[:no_proxy] + end + end + set_autolib_mode if resource.value(:autolib_mode) + options = Array(resource[:build_opts]) + if resource[:proxy_url] and !resource[:proxy_url].empty? + rvmcmd "install", resource[:name], "--proxy", resource[:proxy_url], *options + else + rvmcmd "install", resource[:name], *options + end + set_default if resource.value(:default_use) + end + + def destroy + rvmcmd "uninstall", resource[:name] + end + + def exists? + begin + rvmcmd("list", "strings").split("\n").any? do |line| + line =~ Regexp.new(Regexp.escape(resource[:name])) + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not list RVMs: #{detail}" + end + + end + + def default_use + begin + rvmcmd("list", "default").split("\n").any? do |line| + line =~ Regexp.new(Regexp.escape(resource[:name])) + end + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not list default RVM: #{detail}" + end + end + + def default_use=(value) + set_default if value + end + + def set_default + rvmcmd "alias", "create", "default", resource[:name] + end + + def set_autolib_mode + begin + rvmcmd "autolibs", resource[:autolib_mode] + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not set autolib mode: #{detail}" + end + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_wrapper/wrapper.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_wrapper/wrapper.rb new file mode 100644 index 00000000..6afdb94e --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/provider/rvm_wrapper/wrapper.rb @@ -0,0 +1,37 @@ +# RVM gemset support +Puppet::Type.type(:rvm_wrapper).provide(:wrapper) do + desc "RVM wrapper support." + + has_command(:rvmcmd, '/usr/local/rvm/bin/rvm') do + environment :HOME => ENV['HOME'] + end + + def target_ruby + resource[:target_ruby] + end + + def wrapper_name + resource[:name] + end + + def prefix + resource[:prefix] + end + + def wrapper_filename + filename = prefix ? "#{prefix}_#{wrapper_name}" : wrapper_name + "/usr/local/rvm/bin/#{filename}" + end + + def create + execute([command(:rvmcmd), "wrapper", target_ruby, prefix || "--no-prefix", wrapper_name]) + end + + def destroy + File.delete wrapper_filename + end + + def exists? + File.exists? wrapper_filename + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_alias.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_alias.rb new file mode 100644 index 00000000..82a3d08b --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_alias.rb @@ -0,0 +1,20 @@ +Puppet::Type.newtype(:rvm_alias) do + @doc = "Manage RVM Aliases." + + ensurable + + autorequire(:rvm_system_ruby) do + [self[:target_ruby]] + end + + newparam(:name) do + desc "The name of the alias to be managed." + isnamevar + end + + newparam(:target_ruby) do + desc "The ruby version that is the target of our alias. + For example: 'ruby-1.9.2-p290'" + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gem.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gem.rb new file mode 100644 index 00000000..07b83688 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gem.rb @@ -0,0 +1,157 @@ +Puppet::Type.newtype(:rvm_gem) do + @doc = "Ruby Gem support using RVM." + + def self.title_patterns + [ [ /^(?:(.*)\/)?(.*)$/, [ [ :ruby_version, lambda{|x| x} ], [ :name, lambda{|x| x} ] ] ] ] + end + + ensurable do + desc "What state the gem should be in. + Possible values: + *present* - the gem is installed + *latest* - the gem is installed and is the latest stable version + *absent* - the gem is not installed + version - the gem is installed and matches the given version" + + attr_accessor :latest + + newvalue(:present, :event => :package_installed) do + provider.install + end + + newvalue(:absent, :event => :package_removed) do + provider.uninstall + end + + # Alias the 'present' value. + aliasvalue(:installed, :present) + + newvalue(:latest) do + current = self.retrieve + begin + provider.update + rescue => detail + self.fail "Could not update: #{detail}" + end + + if current == :absent + :package_installed + else + :package_changed + end + end + + newvalue(/./) do + begin + provider.install + rescue => detail + self.fail "Could not update: #{detail}" + end + + if self.retrieve == :absent + :package_installed + else + :package_changed + end + end + + def insync?(is) + @should ||= [] + + @latest ||= nil + @lateststamp ||= (Time.now.to_i - 1000) + # Iterate across all of the should values, and see how they + # turn out. + + @should.each { |should| + case should + when :present + return true unless is == :absent + when :latest + # Short-circuit packages that are not present + return false if is == :absent + + # Don't run 'latest' more than about every 5 minutes + if @latest and ((Time.now.to_i - @lateststamp) / 60) < 5 + #self.debug "Skipping latest check" + else + begin + @latest = provider.latest + @lateststamp = Time.now.to_i + rescue => detail + error = Puppet::Error.new("Could not get latest version: #{detail}") + error.set_backtrace(detail.backtrace) + raise error + end + end + + case is + when Array + if is.include?(@latest) + return true + else + return false + end + when @latest + return true + else + self.debug "#{@resource.name} #{is.inspect} is installed, latest is #{@latest.inspect}" + end + when :absent + return true if is == :absent + when *Array(is) + return true + end + } + + false + end + + def retrieve + if gem = provider.query + gem[:ensure] + else + :absent + end + end + + defaultto :installed + + end + + autorequire(:rvm_system_ruby) do + [self[:ruby_version].split("@").first] + end + + newparam(:name) do + desc "The name of the Ruby gem." + + isnamevar + end + + newparam(:withopts) do + desc "Install the gem with these makefile opts." + end + + newparam(:source) do + desc "If a URL is passed via, then that URL is used as the + remote gem repository; if a source is present but is not a valid URL, it will be + interpreted as the path to a local gem file. If source is not present at all, + the gem will be installed from the default gem repositories." + end + + newparam(:ruby_version) do + desc "The ruby version to use. This should be the fully qualified RVM string + (including gemset if applicable). For example: 'ruby-1.9.2-p136@mygemset' + For a full list of known strings: `rvm list known_strings`." + + defaultto "1.9" + isnamevar + end + + newparam(:proxy_url) do + desc "Proxy to use when downloading ruby installation" + defaultto "" + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gemset.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gemset.rb new file mode 100644 index 00000000..4062946b --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_gemset.rb @@ -0,0 +1,33 @@ +Puppet::Type.newtype(:rvm_gemset) do + @doc = "Manage RVM Gemsets." + + def self.title_patterns + [ [ /^(?:(.*)@)?(.*)$/, [ [ :ruby_version, lambda{|x| x} ], [ :name, lambda{|x| x} ] ] ] ] + end + + ensurable + + autorequire(:rvm_system_ruby) do + [self[:ruby_version]] + end + + newparam(:name) do + desc "The name of the gemset to be managed." + isnamevar + end + + newparam(:ruby_version) do + desc "The ruby version to use. This should be the fully qualified RVM string. + For example: 'ruby-1.9.2-p290' + For a full list of known strings: `rvm list known_strings`." + + defaultto "1.9" + isnamevar + end + + newparam(:proxy_url) do + desc "Proxy to use when downloading ruby installation" + defaultto "" + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_system_ruby.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_system_ruby.rb new file mode 100644 index 00000000..2464dbe5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_system_ruby.rb @@ -0,0 +1,35 @@ +Puppet::Type.newtype(:rvm_system_ruby) do + @doc = "Manage RVM Ruby installations." + + ensurable + + newparam(:name) do + desc "The name of the Ruby to be managed." + isnamevar + end + + newparam(:build_opts) do + desc "Build flags for RVM (e.g.: ['--movable', '--with-libyaml-dir=...', ...])" + defaultto "" + end + + newparam(:proxy_url) do + desc "Proxy to use when downloading ruby installation" + defaultto "" + end + + newparam(:no_proxy) do + desc "exclude addresses from proxy use" + defaultto "" + end + + newproperty(:default_use) do + desc "Should this Ruby be the system default for new terminals?" + defaultto false + end + + newproperty(:autolib_mode) do + desc "Set RVM autolib mode" + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_wrapper.rb b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_wrapper.rb new file mode 100644 index 00000000..9b2df09a --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/lib/puppet/type/rvm_wrapper.rb @@ -0,0 +1,20 @@ +Puppet::Type.newtype(:rvm_wrapper) do + @doc = "Manage RVM Wrappers." + + ensurable + + newparam(:name) do + desc "The name of the command to create a wrapper for to be managed." + isnamevar + end + + newparam(:prefix) do + desc "The prefix of the wrapper command to be managed." + end + + newparam(:target_ruby) do + desc "The ruby version that is the target of our wrapper. + For example: 'ruby-1.9.2-p290'" + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/dependencies.pp b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies.pp new file mode 100644 index 00000000..f673f884 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies.pp @@ -0,0 +1,9 @@ +# Install packages needed by RVM when not using autolibs +class rvm::dependencies { + case $::operatingsystem { + 'Ubuntu','Debian': { require rvm::dependencies::ubuntu } + 'CentOS','RedHat','Fedora','rhel','Amazon','Scientific': { require rvm::dependencies::centos } + 'OracleLinux': { require rvm::dependencies::oraclelinux } + default: {} + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/centos.pp b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/centos.pp new file mode 100644 index 00000000..3ebbdece --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/centos.pp @@ -0,0 +1,25 @@ +# Install packages needed by RVM on RedHat systems when not using autolibs +class rvm::dependencies::centos { + + $version = $::operatingsystem ? { + 'Amazon' => '6.x', + default => $::operatingsystemrelease, + } + + case $version { + /^[67]\..*/: { + ensure_packages(['libcurl-devel']) + } + /^5\..*/: { + ensure_packages(['autoconf']) + ensure_packages(['curl-devel']) + } + default: { + ensure_packages(['curl-devel']) + } + } + + ensure_packages(['which','gcc','gcc-c++','make','gettext-devel','expat-devel','zlib-devel','openssl-devel', + 'perl','cpio','gettext-devel','wget','bzip2','libxml2','libxml2-devel','libxslt','libxslt-devel', + 'readline-devel','patch','git','libyaml-devel','libffi-devel','libtool','bison']) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/oraclelinux.pp b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/oraclelinux.pp new file mode 100644 index 00000000..58fc9771 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/oraclelinux.pp @@ -0,0 +1,7 @@ +# Install packages needed by RVM on Oracle Linux when not using autolibs +class rvm::dependencies::oraclelinux { + + ensure_packages(['which','gcc','gcc-c++','make','gettext-devel','expat-devel','libcurl-devel', + 'zlib-devel','openssl-devel','perl','cpio','expat-devel','gettext-devel','wget','bzip2', + 'libxml2','libxml2-devel','libxslt','libxslt-devel','readline-devel','patch','git']) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/ubuntu.pp b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/ubuntu.pp new file mode 100644 index 00000000..2aa1e8e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/dependencies/ubuntu.pp @@ -0,0 +1,9 @@ +# Install packages needed by RVM on Ubuntu when not using autolibs +class rvm::dependencies::ubuntu { + + ensure_packages(['build-essential','bison','openssl','libreadline6','libreadline6-dev','curl','git-core', + 'zlib1g','zlib1g-dev','libssl-dev','libyaml-dev','libsqlite3-0','libsqlite3-dev','sqlite3','libxml2-dev', + 'autoconf','libc6-dev']) + + ensure_resource('package', 'libxslt1-dev', {'ensure' => 'present', 'alias' => 'libxslt-dev'}) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/gnupg_key.pp b/tools/laptop_puppetisation/modules/rvm/manifests/gnupg_key.pp new file mode 100644 index 00000000..1c0c6c22 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/gnupg_key.pp @@ -0,0 +1,15 @@ +# RVM's GPG key import + +class rvm::gnupg_key( + $key_id = $rvm::params::gnupg_key_id, + $key_server = $rvm::params::key_server) inherits rvm::params { + + gnupg_key { "rvm_${key_id}": + ensure => present, + key_id => $key_id, + user => 'root', + key_server => $key_server, + key_type => public, + } + +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/gpg.pp b/tools/laptop_puppetisation/modules/rvm/manifests/gpg.pp new file mode 100644 index 00000000..edd8b216 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/gpg.pp @@ -0,0 +1,7 @@ +# RVM's GPG key security signing mechanism requires gpg2 for key import / validation + +class rvm::gpg($package = $rvm::params::gpg_package) inherits rvm::params { + + class { '::gnupg': } + +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/group.pp b/tools/laptop_puppetisation/modules/rvm/manifests/group.pp new file mode 100644 index 00000000..6388bc4d --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/group.pp @@ -0,0 +1,7 @@ +# Create the RVM group +class rvm::group inherits rvm::params { + ensure_resource('group', $rvm::params::group, { + 'ensure' => 'present', + 'system' => true, + }) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/init.pp b/tools/laptop_puppetisation/modules/rvm/manifests/init.pp new file mode 100644 index 00000000..61f4a257 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/init.pp @@ -0,0 +1,43 @@ +# Install RVM, create system user a install system level rubies +class rvm( + $version=undef, + $install_rvm=true, + $install_dependencies=false, + $manage_rvmrc=$rvm::params::manage_rvmrc, + $system_users=[], + $system_rubies={}, + $rvm_gems={}, + $proxy_url=$rvm::params::proxy_url, + $no_proxy=$rvm::params::no_proxy, + $key_server=$rvm::params::key_server, + $gnupg_key_id=$rvm::params::gnupg_key_id) inherits rvm::params { + + if $install_rvm { + + # rvm has now autolibs enabled by default so let it manage the dependencies + if $install_dependencies { + class { 'rvm::dependencies': + before => Class['rvm::system'] + } + } + + if $manage_rvmrc { + ensure_resource('class', 'rvm::rvmrc') + } + + class { 'rvm::system': + version => $version, + proxy_url => $proxy_url, + no_proxy => $no_proxy, + key_server => $key_server, + gnupg_key_id => $gnupg_key_id, + } + } + + rvm::system_user{ $system_users: } + create_resources('rvm_system_ruby', $system_rubies, {'ensure' => present, 'proxy_url' => $proxy_url, 'no_proxy' => $no_proxy}) + if $rvm_gems != {} { + validate_hash($rvm_gems) + create_resources('rvm_gem', $rvm_gems ) + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/params.pp b/tools/laptop_puppetisation/modules/rvm/manifests/params.pp new file mode 100644 index 00000000..c247f993 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/params.pp @@ -0,0 +1,29 @@ +# Default module parameters +class rvm::params($manage_group = true) { + + $manage_rvmrc = $::osfamily ? { + 'Windows' => false, + default => true + } + + $group = $::operatingsystem ? { + default => 'rvm', + } + + $proxy_url = undef + $no_proxy = undef + $key_server = 'hkp://keys.gnupg.net' + + # install the gpg key if gpg is installed or being installed in this puppet run + if defined(Class['::gnupg']) or $::gnupg_installed { + $gnupg_key_id = 'D39DC0E3' + } else { + $gnupg_key_id = false + } + + # ignored param, using gnupg module + $gpg_package = $::kernel ? { + /(Linux|Darwin)/ => 'gnupg2', + default => undef, + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/apache.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/apache.pp new file mode 100644 index 00000000..5d1ec8c8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/apache.pp @@ -0,0 +1,105 @@ +# Install Passenger dependencies and Apache module +class rvm::passenger::apache( + $ruby_version, + $version, + $rvm_prefix = '/usr/local', + $mininstances = '1', + $maxpoolsize = '6', + $poolidletime = '300', + $maxinstancesperapp = '0', + $spawnmethod = 'smart-lv2', + $proxy_url = undef, + $package_ensure = undef, + $install_timeout = 600 +) { + + class { 'rvm::passenger::gem': + ruby_version => $ruby_version, + version => $version, + proxy_url => $proxy_url + } + + # TODO: How can we get the gempath automatically using the ruby version + # Can we read the output of a command into a variable? + # e.g. $gempath = `usr/local/rvm/bin/rvm ${ruby_version} exec rvm gemdir` + $gempath = "${rvm_prefix}/rvm/gems/${ruby_version}/gems" + $binpath = "${rvm_prefix}/rvm/bin/" + $gemroot = "${gempath}/passenger-${version}" + + if ( versioncmp( $rvm::passenger::apache::version, '4.0.0' ) < 0 ) { + if ( versioncmp( $rvm::passenger::apache::version, '3.9.0' ) < 0 ) { + $objdir = 'ext' + } else { + $objdir = 'libout' + } + } else { + $objdir = 'buildout' + } + + $modpath = "${gemroot}/${objdir}/apache2" + $modobjectpath = "${modpath}/mod_passenger.so" + + # build the Apache module + # different passenger versions put the built module in different places (ext, libout, buildout) + include apache::dev + + class { 'rvm::passenger::dependencies': } -> + + exec { 'passenger-install-apache2-module': + command => "${binpath}rvm ${ruby_version} exec passenger-install-apache2-module -a", + creates => $modobjectpath, + environment => [ 'HOME=/root', ], + path => '/usr/bin:/usr/sbin:/bin', + require => Class['rvm::passenger::gem','apache::dev'], + timeout => $install_timeout, + } + + # ensure that the passenger apache module build process succeeded by + # checking for the existence of the compiled module object file + file { 'passenger_module_object': + ensure => 'file', + path => $modobjectpath, + require => Exec['passenger-install-apache2-module'], + } + + class { 'apache::mod::passenger': + passenger_root => $gemroot, + passenger_ruby => "${rvm_prefix}/rvm/wrappers/${ruby_version}/ruby", + passenger_max_pool_size => $maxpoolsize, + passenger_pool_idle_time => $poolidletime, + mod_lib_path => $modpath, + mod_package_ensure => $package_ensure, + require => [ Exec['passenger-install-apache2-module'], File['passenger_module_object'], ], + subscribe => Exec['passenger-install-apache2-module'], + } + + case $::osfamily { + # for redhat and (some versions of) debian OSs Apache configures + # passenger_extra.conf with the details that should be located in + # passenger.conf; passenger.conf can't be written to directly + # without conflicting with apache module settings for that file, but + # copying the file contents works fine + 'debian','redhat': { + case $::osfamily { + 'redhat': { + $apache_mods_path = '/etc/httpd/conf.d' + } + 'debian': { + $apache_mods_path = '/etc/apache2/mods-available' + } + default: { + $apache_mods_path = '/etc/httpd/conf.d' + } + } + exec { 'copy passenger_extra.conf to passenger.conf': + command => "/bin/cp ${apache_mods_path}/passenger_extra.conf ${apache_mods_path}/passenger.conf", + unless => "/usr/bin/diff ${apache_mods_path}/passenger_extra.conf ${apache_mods_path}/passenger.conf", + onlyif => "test -f ${apache_mods_path}/passenger_extra.conf", + environment => [ 'HOME=/root', ], + path => '/usr/bin:/usr/sbin:/bin', + require => Class['apache::mod::passenger'], + } + } + default: {} + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies.pp new file mode 100644 index 00000000..9e994c73 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies.pp @@ -0,0 +1,9 @@ +# Package dependencies for Passenger +class rvm::passenger::dependencies { + case $::operatingsystem { + 'Ubuntu','Debian': { require rvm::passenger::dependencies::ubuntu } + 'CentOS','RedHat','Fedora','rhel','Amazon','Scientific': { require rvm::passenger::dependencies::centos } + 'OracleLinux': { require rvm::passenger::dependencies::oraclelinux } + default: {} + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/centos.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/centos.pp new file mode 100644 index 00000000..c13817df --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/centos.pp @@ -0,0 +1,17 @@ +# Package dependencies for Passenger on RedHat +class rvm::passenger::dependencies::centos { + + $version = $::operatingsystem ? { + 'Amazon' => '6.x', + default => $::operatingsystemrelease, + } + + case $version { + /^[67]\..*/: { + ensure_packages(['libcurl-devel']) + } + default: { + ensure_packages(['curl-devel']) + } + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/oraclelinux.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/oraclelinux.pp new file mode 100644 index 00000000..fa562f50 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/oraclelinux.pp @@ -0,0 +1,4 @@ +# Package dependencies for Passenger on Oracle Linux +class rvm::passenger::dependencies::oraclelinux { + ensure_packages(['libcurl-devel']) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/ubuntu.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/ubuntu.pp new file mode 100644 index 00000000..01c86d55 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/dependencies/ubuntu.pp @@ -0,0 +1,4 @@ +# Package dependencies for Passenger on Ubuntu +class rvm::passenger::dependencies::ubuntu { + ensure_packages(['curl','libcurl4-gnutls-dev']) +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/passenger/gem.pp b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/gem.pp new file mode 100644 index 00000000..aaefd9ad --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/passenger/gem.pp @@ -0,0 +1,11 @@ +# Install the passenger gem +class rvm::passenger::gem($ruby_version, $version, $proxy_url = undef ) { + $ruby_version_only = regsubst($ruby_version,'([^@]+)(@(.+))?','\1') + rvm_gem { + 'passenger': + ensure => $version, + require => Rvm_system_ruby[$ruby_version_only], + ruby_version => $ruby_version, + proxy_url => $proxy_url; + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/rvmrc.pp b/tools/laptop_puppetisation/modules/rvm/manifests/rvmrc.pp new file mode 100644 index 00000000..6870304b --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/rvmrc.pp @@ -0,0 +1,19 @@ +# Configure the /etc/rvmrc file +class rvm::rvmrc( + $manage_group = $rvm::params::manage_group, + $template = 'rvm/rvmrc.erb', + $umask = 'u=rwx,g=rwx,o=rx', + $max_time_flag = undef, + $autoupdate_flag = 0, + $silence_path_mismatch_check_flag = undef) inherits rvm::params { + + if $manage_group { include rvm::group } + + file { '/etc/rvmrc': + content => template($template), + mode => '0664', + owner => 'root', + group => $rvm::params::group, + before => Exec['system-rvm'], + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/system.pp b/tools/laptop_puppetisation/modules/rvm/manifests/system.pp new file mode 100644 index 00000000..968edcbf --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/system.pp @@ -0,0 +1,74 @@ +# Install the RVM system +class rvm::system( + $version=undef, + $proxy_url=undef, + $no_proxy=undef, + $key_server=undef, + $home=$::root_home, + $gnupg_key_id=$rvm::params::gnupg_key_id) inherits rvm::params { + + $actual_version = $version ? { + undef => 'latest', + 'present' => 'latest', + default => $version, + } + + # curl needs to be installed + if ! defined(Package['curl']) { + case $::kernel { + 'Linux': { + ensure_packages(['curl']) + Package['curl'] -> Exec['system-rvm'] + } + default: {} + } + } + + $http_proxy_environment = $proxy_url ? { + undef => [], + default => ["http_proxy=${proxy_url}", "https_proxy=${proxy_url}"] + } + $no_proxy_environment = $no_proxy ? { + undef => [], + default => ["no_proxy=${no_proxy}"] + } + $proxy_environment = concat($http_proxy_environment, $no_proxy_environment) + $environment = concat($proxy_environment, ["HOME=${home}"]) + + # install the gpg key + if $gnupg_key_id { + class { 'rvm::gnupg_key': + key_server => $key_server, + key_id => $gnupg_key_id, + before => Exec['system-rvm'], + } + } + + exec { 'system-rvm': + path => '/usr/bin:/usr/sbin:/bin:/usr/local/bin', + command => "curl -fsSL https://get.rvm.io | bash -s -- --version ${actual_version}", + creates => '/usr/local/rvm/bin/rvm', + environment => $environment, + } + + # the fact won't work until rvm is installed before puppet starts + if getvar('::rvm_version') and !empty($::rvm_version) { + if ($version != undef) and ($version != present) and ($version != $::rvm_version) { + + if defined(Class['rvm::gnupg_key']) { + Class['rvm::gnupg_key'] -> Exec['system-rvm-get'] + } + + # Update the rvm installation to the version specified + notify { 'rvm-get_version': + message => "RVM updating from version ${::rvm_version} to ${version}", + } -> + exec { 'system-rvm-get': + path => '/usr/local/rvm/bin:/usr/bin:/usr/sbin:/bin', + command => "rvm get ${version}", + before => Exec['system-rvm'], # so it doesn't run after being installed the first time + environment => $environment, + } + } + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/manifests/system_user.pp b/tools/laptop_puppetisation/modules/rvm/manifests/system_user.pp new file mode 100644 index 00000000..ac0799ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/manifests/system_user.pp @@ -0,0 +1,40 @@ +# Create a user that belongs to the correct group to have access to RVM +define rvm::system_user ( + $create = false, + $manage_group = undef) { + + include rvm::params + + $manage_group_real = $manage_group ? { + undef => $rvm::params::manage_group, + default => $manage_group + } + + if $create { + ensure_resource('user', $name, { + 'ensure' => 'present', + 'system' => true, + }) + User[$name] -> Exec["rvm-system-user-${name}"] + } + + if $manage_group_real { + include rvm::group + Group[$rvm::params::group] -> Exec["rvm-system-user-${name}"] + } + + $add_to_group = $::osfamily ? { + 'Darwin' => "/usr/sbin/dseditgroup -o edit -a ${name} -t user ${rvm::params::group}", + 'FreeBSD' => "/usr/sbin/pw groupmod ${rvm::params::group} -m ${name}", + default => "/usr/sbin/usermod -a -G ${rvm::params::group} ${name}", + } + $check_in_group = $::osfamily ? { + 'Darwin' => "/usr/bin/dsmemberutil checkmembership -U ${name} -G ${rvm::params::group} | grep -q 'user is a member'", + 'FreeBSD' => "/usr/bin/id ${name} | grep -q '(${rvm::params::group})'", + default => "/bin/cat /etc/group | grep '^${rvm::params::group}:' | grep -qw ${name}", + } + exec { "rvm-system-user-${name}": + command => $add_to_group, + unless => $check_in_group, + } +} diff --git a/tools/laptop_puppetisation/modules/rvm/metadata.json b/tools/laptop_puppetisation/modules/rvm/metadata.json new file mode 100644 index 00000000..8f83783c --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/metadata.json @@ -0,0 +1,121 @@ +{ + "name": "maestrodev-rvm", + "version": "1.13.1", + "author": "maestrodev & Brandon Turner ", + "summary": "A puppet module for installing and using RVM (Ruby Version Manager)", + "license": "Modified BSD License", + "source": "https://github.com/maestrodev/puppet-rvm", + "project_page": "https://github.com/maestrodev/puppet-rvm", + "issues_url": "https://github.com/maestrodev/puppet-rvm/issues", + "dependencies": [ + {"name":"puppetlabs/stdlib","version_requirement":">=4.2.0"}, + {"name":"golja/gnupg","version_requirement":">=1.2.0"} + ], + "data_provider": null, + "description": "Installing and using RVM (Ruby Version Manager)", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "11 SP1" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04" + ] + }, + { + "operatingsystem": "Solaris", + "operatingsystemrelease": [ + "10", + "11" + ] + }, + { + "operatingsystem": "Windows", + "operatingsystemrelease": [ + "Server 2003", + "Server 2003 R2", + "Server 2008", + "Server 2008 R2", + "Server 2012", + "Server 2012 R2", + "7", + "8" + ] + }, + { + "operatingsystem": "AIX", + "operatingsystemrelease": [ + "5.3", + "6.1", + "7.1" + ] + }, + { + "operatingsystem": "Darwin", + "operatingsystemrelease": [ + "10", + "11", + "12", + "13" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": ">=3.2.0" + }, + { + "name": "puppet", + "version_requirement": ">=3.0.0" + } + ] +} diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64-docker.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64-docker.yml new file mode 100644 index 00000000..7ec622ec --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64-docker.yml @@ -0,0 +1,23 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + image: devopsil/puppet:3.5.1 + # ip: localhost + hypervisor : docker + docker_image_commands: + - yum -y install tar + - useradd vagrant + - "sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config" + - "sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config" + docker_cmd: + - 'sh' + - '-c' + - 'service sshd start; tail -f /dev/null' +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64.yml new file mode 100644 index 00000000..5b60f7ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/centos-65-x64.yml @@ -0,0 +1,14 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-65-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64-docker.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64-docker.yml new file mode 100644 index 00000000..d7ecfb4f --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64-docker.yml @@ -0,0 +1,22 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + debian-7-x64: + roles: + - master + platform: debian-7-amd64 + image: debian:7 + # ip: localhost + hypervisor : docker + docker_image_commands: + - useradd vagrant + - "sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config" + - "sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config" + docker_cmd: + - 'sh' + - '-c' + - 'service ssh start; tail -f /dev/null' +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64.yml new file mode 100644 index 00000000..3737e5d4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-7-x64.yml @@ -0,0 +1,14 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + debian-7-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-73-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-73-x64.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-73-x64.yml new file mode 100644 index 00000000..db65d262 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/debian-73-x64.yml @@ -0,0 +1,14 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + debian-73-x64: + roles: + - master + platform: debian-7-amd64 + box : debian-73-x64-virtualbox-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/debian-73-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/default.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/default.yml new file mode 100644 index 00000000..7ec622ec --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/default.yml @@ -0,0 +1,23 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + image: devopsil/puppet:3.5.1 + # ip: localhost + hypervisor : docker + docker_image_commands: + - yum -y install tar + - useradd vagrant + - "sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config" + - "sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config" + docker_cmd: + - 'sh' + - '-c' + - 'service sshd start; tail -f /dev/null' +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64-docker.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64-docker.yml new file mode 100644 index 00000000..0b714515 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64-docker.yml @@ -0,0 +1,22 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-14.04-amd64 + image: ubuntu:trusty + # ip: localhost + hypervisor : docker + docker_image_commands: + - useradd vagrant + - "sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config" + - "sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config" + docker_cmd: + - 'sh' + - '-c' + - 'service ssh start; tail -f /dev/null' +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 00000000..7e173ffe --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,14 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-14.04-amd64 + box : ubuntu-server-1404-x64-cloud + box_url : https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box + hypervisor : vagrant +CONFIG: + log_level: debug + type: git diff --git a/tools/laptop_puppetisation/modules/rvm/spec/acceptance/rvm_system_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/rvm_system_spec.rb new file mode 100644 index 00000000..fc876d76 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/acceptance/rvm_system_spec.rb @@ -0,0 +1,419 @@ +require "spec_helper_acceptance" + +describe "rvm" do + + # host variables + let(:osfamily) { fact("osfamily") } + let(:osname) { fact("operatingsystem") } + let(:osversion) { fact("operatingsystemrelease") } + + # rvm config + let(:rvm_path) { "/usr/local/rvm/" } + + # ruby 1.9.3 config + let(:ruby19_version) { "ruby-1.9.3-p547" } # chosen for RVM binary support across nodesets + let(:ruby19_environment) { "#{rvm_path}environments/#{ruby19_version}" } + let(:ruby19_bin) { "#{rvm_path}rubies/#{ruby19_version}/bin/" } + let(:ruby19_gems) { "#{rvm_path}gems/#{ruby19_version}/gems/" } + let(:ruby19_gemset) { "myproject" } + let(:ruby19_and_gemset) { "#{ruby19_version}@#{ruby19_gemset}" } + + # ruby 2.0 config + let(:ruby20_version) { "ruby-2.0.0-p481" } # chosen for RVM binary support across nodesets + let(:ruby20_environment) { "#{rvm_path}environments/#{ruby20_version}" } + let(:ruby20_bin) { "#{rvm_path}rubies/#{ruby20_version}/bin/" } + let(:ruby20_gems) { "#{rvm_path}gems/#{ruby20_version}/gems/" } + let(:ruby20_gemset) { "myproject" } + let(:ruby20_and_gemset) { "#{ruby20_version}@#{ruby20_gemset}" } + + # passenger baseline configuration + let(:service_name) { + case osfamily + when "Debian" + "apache2" + when "RedHat" + "httpd" + end + } + let(:mod_dir) { + case osfamily + when "Debian" + "/etc/apache2/mods-available/" + when "RedHat" + "/etc/httpd/conf.d/" + end + } + let(:rackapp_user) { + case osfamily + when "Debian" + "www-data" + when "RedHat" + "apache" + end + } + let(:rackapp_group) { + case osfamily + when "Debian" + "www-data" + when "RedHat" + "apache" + end + } + let(:conf_file) { "#{mod_dir}passenger.conf" } + let(:load_file) { "#{mod_dir}passenger.load" } + + # baseline manifest + let(:manifest) { + <<-EOS + if $::osfamily == 'RedHat' { + class { 'epel': + before => Class['rvm'], + } + } + + # ensure rvm doesn't timeout finding binary rubies + class { 'rvm::rvmrc': + max_time_flag => '20', + } -> + + class { 'rvm': } -> + rvm::system_user { 'vagrant': } + EOS + } + + it "rvm should install and configure system user" do + # Run it twice and test for idempotency + apply_manifest(manifest, :catch_failures => true) + apply_manifest(manifest, :catch_changes => true) + shell("/usr/local/rvm/bin/rvm list") do |r| + r.stdout.should =~ Regexp.new(Regexp.escape("# No rvm rubies installed yet.")) + r.exit_code.should be_zero + end + end + + context "when installing rubies" do + + let(:manifest) { + super() + <<-EOS + rvm_system_ruby { + '#{ruby19_version}': + ensure => 'present', + default_use => false; + '#{ruby20_version}': + ensure => 'present', + default_use => false; + } + EOS + } + + it "should install with no errors" do + apply_manifest(manifest, :catch_failures => true) + apply_manifest(manifest, :catch_changes => true) + end + + it "should reflect installed rubies" do + shell("/usr/local/rvm/bin/rvm list") do |r| + r.stdout.should =~ Regexp.new(Regexp.escape("\n #{ruby19_version}")) + r.stdout.should =~ Regexp.new(Regexp.escape("\n #{ruby20_version}")) + r.exit_code.should be_zero + end + end + + context "and installing gems" do + let(:gem_name) { "simple-rss" } # used because has no dependencies + let(:gem_version) { "1.3.1" } + + let(:gemset_manifest) { + manifest + <<-EOS + rvm_gemset { + '#{ruby19_and_gemset}': + ensure => present, + require => Rvm_system_ruby['#{ruby19_version}']; + } + rvm_gem { + '#{ruby19_and_gemset}/#{gem_name}': + ensure => '#{gem_version}', + require => Rvm_gemset['#{ruby19_and_gemset}']; + } + rvm_gemset { + '#{ruby20_and_gemset}': + ensure => present, + require => Rvm_system_ruby['#{ruby20_version}']; + } + rvm_gem { + '#{ruby20_and_gemset}/#{gem_name}': + ensure => '#{gem_version}', + require => Rvm_gemset['#{ruby20_and_gemset}']; + } + EOS + } + + it "should install with no errors" do + apply_manifest(gemset_manifest, :catch_failures => true) + apply_manifest(gemset_manifest, :catch_changes => true) + end + + it "should reflect installed gems and gemsets" do + shell("/usr/local/rvm/bin/rvm #{ruby19_version} gemset list") do |r| + r.stdout.should =~ Regexp.new(Regexp.escape("\n=> (default)")) + r.stdout.should =~ Regexp.new(Regexp.escape("\n global")) + r.stdout.should =~ Regexp.new(Regexp.escape("\n #{ruby19_gemset}")) + r.exit_code.should be_zero + end + + shell("/usr/local/rvm/bin/rvm #{ruby20_version} gemset list") do |r| + r.stdout.should =~ Regexp.new(Regexp.escape("\n=> (default)")) + r.stdout.should =~ Regexp.new(Regexp.escape("\n global")) + r.stdout.should =~ Regexp.new(Regexp.escape("\n #{ruby20_gemset}")) + r.exit_code.should be_zero + end + end + end + end + + context "when installing jruby" do + let(:jruby_version) { "jruby-1.7.6" } + + let(:manifest) { + super() + <<-EOS + rvm_system_ruby { '#{jruby_version}': + ensure => 'present', + default_use => false; + } + EOS + } + + it 'should install with no errors' do + apply_manifest(manifest, :catch_failures => true) + apply_manifest(manifest, :catch_changes => true) + end + + it 'should reflect installed rubies' do + shell("/usr/local/rvm/bin/rvm list") do |r| + r.stdout.should =~ Regexp.new(Regexp.escape("\n #{jruby_version}")) + r.exit_code.should be_zero + end + end + end + + context "when installing passenger 3.0.x" do + + let(:passenger_version) { "3.0.21" } + let(:passenger_domain) { "passenger3.example.com" } + + let(:passenger_ruby) { "#{rvm_path}wrappers/#{ruby19_version}/ruby" } + let(:passenger_root) { "#{ruby19_gems}passenger-#{passenger_version}" } + # particular to 3.0.x (may or may not also work with 2.x?) + let(:passenger_module_path) { "#{passenger_root}/ext/apache2/mod_passenger.so" } + + let(:manifest) { + super() + <<-EOS + rvm_system_ruby { + '#{ruby19_version}': + ensure => 'present', + default_use => false, + } + class { 'apache': + service_enable => false, # otherwise detects changes in 2nd run in ubuntu and docker + } + class { 'rvm::passenger::apache': + version => '#{passenger_version}', + ruby_version => '#{ruby19_version}', + mininstances => '3', + maxinstancesperapp => '0', + maxpoolsize => '30', + spawnmethod => 'smart-lv2', + } + /* a simple ruby rack 'hello world' app */ + file { '/var/www/passenger': + ensure => directory, + owner => '#{rackapp_user}', + group => '#{rackapp_group}', + require => Class['rvm::passenger::apache'], + } + file { '/var/www/passenger/config.ru': + ensure => file, + owner => '#{rackapp_user}', + group => '#{rackapp_group}', + content => "app = proc { |env| [200, { \\"Content-Type\\" => \\"text/html\\" }, [\\"hello world\\"]] }\\nrun app", + require => File['/var/www/passenger'] , + } + apache::vhost { '#{passenger_domain}': + port => '80', + docroot => '/var/www/passenger/public', + docroot_group => '#{rackapp_group}' , + docroot_owner => '#{rackapp_user}' , + custom_fragment => "PassengerRuby #{passenger_ruby}\\nRailsEnv development" , + default_vhost => true , + require => File['/var/www/passenger/config.ru'] , + } + EOS + } + + it "should install with no errors" do + # Run it twice and test for idempotency + apply_manifest(manifest, :catch_failures => true) + # swapping expectations under Ubuntu 12.04, 14.04 - apache2-prefork-dev is being purged/restored by puppetlabs/apache, which is beyond the scope of this module + if osname == 'Ubuntu' && ['12.04', '14.04'].include?(osversion) + apply_manifest(manifest, :expect_changes => true) + else + apply_manifest(manifest, :catch_changes => true) + end + + shell("/usr/local/rvm/bin/rvm #{ruby19_version} do #{ruby19_bin}gem list passenger | grep \"passenger (#{passenger_version})\"").exit_code.should be_zero + end + + it "should be running" do + service(service_name) do |s| + s.should_not be_enabled + s.should be_running + end + end + + it "should answer" do + shell("/usr/bin/curl localhost:80") do |r| + r.stdout.should =~ /^hello world<\/b>$/ + r.exit_code.should == 0 + end + end + + it "should output status via passenger-status" do + shell("rvmsudo_secure_path=1 /usr/local/rvm/bin/rvm #{ruby19_version} do passenger-status") do |r| + # spacing may vary + r.stdout.should =~ /[\-]+ General information [\-]+/ + r.stdout.should =~ /max[ ]+= [0-9]+/ + r.stdout.should =~ /count[ ]+= [0-9]+/ + r.stdout.should =~ /active[ ]+= [0-9]+/ + r.stdout.should =~ /inactive[ ]+= [0-9]+/ + r.stdout.should =~ /Waiting on global queue: [0-9]+/ + r.exit_code.should == 0 + end + end + + it "module loading should be configured as expected" do + file(load_file) do |f| + f.should contain "LoadModule passenger_module #{passenger_module_path}" + end + end + + it "module behavior should be configured as expected" do + file(conf_file) do |f| + f.should contain "PassengerRoot \"#{passenger_root}\"" + f.should contain "PassengerRuby \"#{passenger_ruby}\"" + end + end + + end + + context "when installing passenger 4.0.x" do + + let(:passenger_version) { "4.0.46" } + let(:passenger_domain) { "passenger4.example.com" } + + let(:passenger_ruby) { "#{rvm_path}wrappers/#{ruby20_version}/ruby" } + let(:passenger_root) { "#{ruby20_gems}passenger-#{passenger_version}" } + # particular to passenger 4.0.x + let(:passenger_module_path) { "#{passenger_root}/buildout/apache2/mod_passenger.so" } + + let(:manifest) { + super() + <<-EOS + rvm_system_ruby { + '#{ruby20_version}': + ensure => 'present', + default_use => false, + } + class { 'apache': + service_enable => false, # otherwise detects changes in 2nd run in ubuntu and docker + } + class { 'rvm::passenger::apache': + version => '#{passenger_version}', + ruby_version => '#{ruby20_version}', + mininstances => '3', + maxinstancesperapp => '0', + maxpoolsize => '30', + spawnmethod => 'smart-lv2', + } + /* a simple ruby rack 'hello world' app */ + file { '/var/www/passenger': + ensure => directory, + owner => '#{rackapp_user}', + group => '#{rackapp_group}', + require => Class['rvm::passenger::apache'], + } + file { '/var/www/passenger/config.ru': + ensure => file, + owner => '#{rackapp_user}', + group => '#{rackapp_group}', + content => "app = proc { |env| [200, { \\"Content-Type\\" => \\"text/html\\" }, [\\"hello world\\"]] }\\nrun app", + require => File['/var/www/passenger'] , + } + apache::vhost { '#{passenger_domain}': + port => '80', + docroot => '/var/www/passenger/public', + docroot_group => '#{rackapp_group}' , + docroot_owner => '#{rackapp_user}' , + custom_fragment => "PassengerRuby #{passenger_ruby}\\nRailsEnv development" , + default_vhost => true , + require => File['/var/www/passenger/config.ru'] , + } + EOS + } + + it "should install with no errors" do + # Run it twice and test for idempotency + apply_manifest(manifest, :catch_failures => true) + # swapping expectations under Ubuntu 14.04 - apache2-prefork-dev is being purged/restored by puppetlabs/apache, which is beyond the scope of this module + if osname == 'Ubuntu' && ['14.04'].include?(osversion) + apply_manifest(manifest, :expect_changes => true) + else + apply_manifest(manifest, :catch_changes => true) + end + + shell("/usr/local/rvm/bin/rvm #{ruby20_version} do #{ruby20_bin}gem list passenger | grep \"passenger (#{passenger_version})\"").exit_code.should be_zero + end + + it "should be running" do + service(service_name) do |s| + s.should_not be_enabled + s.should be_running + end + end + + it "should answer" do + shell("/usr/bin/curl localhost:80") do |r| + r.stdout.should =~ /^hello world<\/b>$/ + r.exit_code.should == 0 + end + end + + it "should output status via passenger-status" do + shell("rvmsudo_secure_path=1 /usr/local/rvm/bin/rvm #{ruby20_version} do passenger-status") do |r| + # spacing may vary + r.stdout.should =~ /[\-]+ General information [\-]+/ + r.stdout.should =~ /Max pool size \: [0-9]+/ + r.stdout.should =~ /Processes \: [0-9]+/ + r.stdout.should =~ /Requests in top\-level queue \: [0-9]+/ + r.stdout.should =~ /[\-]+ Application groups [\-]+/ + # the following will only appear after a request has been made, as in "should answer to" above + r.stdout.should =~ /App root\: \/var\/www\/passenger/ + r.stdout.should =~ /Requests in queue\: [0-9]+/ + r.exit_code.should == 0 + end + end + + it "module loading should be configured as expected" do + file(load_file) do |f| + f.should contain "LoadModule passenger_module #{passenger_module_path}" + end + end + + it "module behavior should be configured as expected" do + file(conf_file) do |f| + f.should contain "PassengerRoot \"#{passenger_root}\"" + f.should contain "PassengerRuby \"#{passenger_ruby}\"" + end + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/dependencies_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/dependencies_spec.rb new file mode 100644 index 00000000..552770c0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/dependencies_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe 'rvm::dependencies' do + + packages = ['which','gcc','autoconf','libcurl-devel','build-essential'] + + let(:facts) {{}} + + shared_examples 'package creation' do |packages_to_have| + packages_to_have.each {|p| it { should contain_package(p)} } + (packages-packages_to_have).each {|p| it { should_not contain_package(p)} } + end + + shared_context 'redhat_facts' do |operatingsystem, operatingsystemrelease| + let(:facts) { super().merge({ + :osfamily => "RedHat", + :operatingsystem => operatingsystem, + :operatingsystemrelease => operatingsystemrelease + }) } + end + + shared_examples 'redhat' do |packages_to_have| + it_behaves_like 'package creation', packages_to_have + ['which','gcc'] + end + + shared_examples 'redhat5' do |operatingsystem, operatingsystemrelease| + include_context 'redhat_facts', operatingsystem, operatingsystemrelease + it_behaves_like 'redhat', ['autoconf'] + end + + shared_examples 'redhat6' do |operatingsystem, operatingsystemrelease| + include_context 'redhat_facts', operatingsystem, operatingsystemrelease + it_behaves_like 'redhat', ['libcurl-devel'] + end + + shared_examples 'debian' do |operatingsystem| + let(:facts) {{ + :osfamily => "Debian", + :operatingsystem => operatingsystem + }} + it_behaves_like 'package creation', ['autoconf','build-essential'] + end + + + context 'RedHat' do + operatingsystems = ['centos', 'fedora', 'rhel', 'redhat', 'scientific'] + versions = { '5.0' => 'redhat5', '6.4' => 'redhat6' } + operatingsystems.each do |os| + context os, :compile do + versions.each {|version,example| it_behaves_like example, os, version } + end + end + + context 'amazon linux', :compile do + let(:facts) {{ :operatingsystemmajrelease => "3" }} + it_behaves_like 'redhat6', 'Amazon', '3.4.43-43.43.amzn1.x86_64' + end + end + + context 'debian', :compile do + it_behaves_like 'debian', 'ubuntu' + end + + context 'other', :compile do + let(:facts) {{ :operatingsystem => 'xxx' }} + it_behaves_like 'package creation', [] + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/gnupg_key_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/gnupg_key_spec.rb new file mode 100644 index 00000000..dc2b1a26 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/gnupg_key_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'rvm::gnupg_key', :compile do + + let(:facts) {{ :gnupg_installed => true }} + + it { should contain_gnupg_key('rvm_D39DC0E3') } + +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/gpg_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/gpg_spec.rb new file mode 100644 index 00000000..06b3f969 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/gpg_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe 'rvm::gpg' do + + context "RedHat", :compile do + let(:facts) {{ + :kernel => 'Linux', + :osfamily => 'RedHat' + }} + it { should contain_package('gnupg') } + end + + context "Debian", :compile do + let(:facts) {{ + :kernel => 'Linux', + :osfamily => 'Debian' + }} + it { should contain_package('gnupg') } + end + + # Not supported by gnupg module + # context "OS X", :compile do + # let(:facts) {{ + # :kernel => 'Darwin', + # :osfamily => 'Darwin' + # }} + # it { should contain_package('gnupg') } + # end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/init_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/init_spec.rb new file mode 100644 index 00000000..c70188c4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/init_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'rvm' do + + let(:facts) {{ + :rvm_version => '', + :root_home => '/root' + }} + + context "default parameters", :compile do + it { should_not contain_class('rvm::dependencies') } + it { should contain_class('rvm::system') } + end + + context "with install_rvm false", :compile do + let(:params) {{ + :install_rvm => false + }} + it { should_not contain_class('rvm::dependencies') } + it { should_not contain_class('rvm::system') } + end + + context "with system_rubies", :compile do + let(:params) {{ + :system_rubies => { + 'ruby-1.9' => { + 'default_use' => true + }, + 'ruby-2.0' => {} + } + }} + it { should contain_rvm_system_ruby('ruby-1.9').with({ + :ensure => 'present', + :default_use => true + }) } + it { should contain_rvm_system_ruby('ruby-2.0').with({ + :ensure => 'present', + :default_use => nil + }) } + end + + context "with system_users", :compile do + let(:params) {{ :system_users => ['john','doe'] }} + it { should contain_rvm__system_user('john') } + it { should contain_rvm__system_user('doe') } + end + + context "with no gnupg key id", :compile do + let(:params) {{ :gnupg_key_id => false }} + it { should_not contain_gnupg_key('rvm_D39DC0E3') } + it { should_not contain_gnupg_key('rvm_') } + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/rvmrc_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/rvmrc_spec.rb new file mode 100644 index 00000000..19e97585 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/rvmrc_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe 'rvm::rvmrc' do + let(:file) { '/etc/rvmrc' } + let(:pre_condition) { "exec {'system-rvm': path => '/bin'}" } + + context "default parameters", :compile do + it { should contain_file(file).with_group('rvm') } + it { should contain_file(file).with_content(%r{^umask u=rwx,g=rwx,o=rx$}) } + it { should contain_file(file).with_content(%r{^rvm_autoupdate_flag=0$}) } + it { should_not contain_file(file).with_content(%r{rvm_max_time_flag}) } + end + + context "with max_time_flag", :compile do + let(:params) {{ :max_time_flag => 20 }} + it { should contain_file(file).with_content(%r{^export rvm_max_time_flag=20$}) } + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/classes/system_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/classes/system_spec.rb new file mode 100644 index 00000000..5b6f02d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/classes/system_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' + +describe 'rvm::system' do + + # assume RVM is already installed + let(:facts) {{ + :rvm_version => '1.10.0', + :root_home => '/root' + }} + + context "default parameters", :compile do + it { should_not contain_exec('system-rvm-get') } + + it do + should contain_exec('system-rvm').with({ + 'path' => '/usr/bin:/usr/sbin:/bin:/usr/local/bin', + }) + end + end + + context "with present version", :compile do + let(:params) {{ :version => 'present' }} + it { should_not contain_exec('system-rvm-get') } + end + + context "with latest version", :compile do + let(:params) {{ :version => 'latest' }} + it { should contain_exec('system-rvm-get').with_command('rvm get latest') } + end + + context "with explicit version", :compile do + let(:params) {{ :version => '1.20.0' }} + it { should contain_exec('system-rvm-get').with_command('rvm get 1.20.0') } + end + + context "with proxy_url parameter", :compile do + let(:params) {{ :version => 'latest', :proxy_url => 'http://dummy.bogus.local:8080' }} + it { should contain_exec('system-rvm-get').with_environment("[\"http_proxy=#{params[:proxy_url]}\", \"https_proxy=#{params[:proxy_url]}\", \"HOME=/root\"]") } + end + + context "with no_proxy parameter", :compile do + let(:params) {{ :version => 'latest', :proxy_url => 'http://dummy.bogus.local:8080', :no_proxy => '.example.local' }} + it { should contain_exec('system-rvm-get').with_environment("[\"http_proxy=#{params[:proxy_url]}\", \"https_proxy=#{params[:proxy_url]}\", \"no_proxy=#{params[:no_proxy]}\", \"HOME=/root\"]") } + end + + context "with gnupg", :compile do + let(:pre_condition) { "class { '::gnupg': }" } + it { should contain_gnupg_key('rvm_D39DC0E3').with_key_id('D39DC0E3').with_key_server('hkp://keys.gnupg.net') } + end + + context "with gnupg customized", :compile do + let(:params) {{ :key_server => 'hkp://example.com', :gnupg_key_id => 'AAAAAAAA' }} + let(:pre_condition) { "class { '::gnupg': }" } + it { should contain_gnupg_key('rvm_AAAAAAAA').with_key_id('AAAAAAAA').with_key_server('hkp://example.com') } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_alias_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_alias_spec.rb new file mode 100644 index 00000000..26da65e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_alias_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe 'rvm_alias' do + + let(:title) { '2.0' } + let(:params) {{ :target_ruby => '2.0-384' }} + + context "when using default parameters", :compile do + it { should contain_rvm_alias('2.0').with_target_ruby('2.0-384') } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gem_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gem_spec.rb new file mode 100644 index 00000000..f15c2733 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gem_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'rvm_gem' do + + let(:title) { 'thin' } + let(:params) {{ :ruby_version => '2.0' }} + let(:pre_condition) { "rvm_system_ruby { '2.0': }" } + + context "when using default parameters", :compile do + # TODO test autorequirement + it { should contain_rvm_gem('thin') } #.that_requires("Rvm_system_ruby[2.0]") + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gemset_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gemset_spec.rb new file mode 100644 index 00000000..44ac4b99 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_gemset_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'rvm_gemset' do + + let(:title) { 'ruby-1.9@myproject' } + + context "when using default parameters", :compile do + it { should contain_rvm_gemset('ruby-1.9@myproject').with_ruby_version('ruby-1.9') } + end + + context "when setting ruby_version", :compile do + let(:params) {{ :ruby_version => '1.9'}} + it { should contain_rvm_gemset('ruby-1.9@myproject').with_ruby_version('1.9') } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_system_ruby_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_system_ruby_spec.rb new file mode 100644 index 00000000..58fa119e --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_system_ruby_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe 'rvm_system_ruby' do + + let(:title) { '2.0' } + + context "when using default parameters", :compile do + it { should contain_rvm_system_ruby('2.0') } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_wrapper_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_wrapper_spec.rb new file mode 100644 index 00000000..a36335f4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/rvm_wrapper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'rvm_wrapper' do + + let(:title) { 'god' } + let(:params) {{ + :target_ruby => 'ruby-1.9.3-p448', + :prefix => 'bootup', + :ensure => 'present' + }} + + context "when using default parameters", :compile do + it { should contain_rvm_wrapper('god').with_prefix('bootup') } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/defines/system_user_spec.rb b/tools/laptop_puppetisation/modules/rvm/spec/defines/system_user_spec.rb new file mode 100644 index 00000000..0577dc1c --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/defines/system_user_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe 'rvm::system_user' do + + let(:username) { 'johndoe' } + let(:group) { 'rvm' } + let(:title) { username } + + context "when using default parameters", :compile do + it { should contain_user(username) } + it { should contain_group(group) } + it { should contain_exec("rvm-system-user-#{username}").with_command("/usr/sbin/usermod -a -G #{group} #{username}") } + end + + context "when using default parameters on FreeBSD", :compile do + let(:facts) {{ + :osfamily => 'FreeBSD', + }} + + it { should contain_user(username) } + it { should contain_group(group) } + it { should contain_exec("rvm-system-user-#{username}").with_command("/usr/sbin/pw groupmod #{group} -m #{username}") } + end + + context "when using default parameters on Darwin", :compile do + let(:facts) {{ + :osfamily => 'Darwin', + }} + + it { should contain_user(username) } + it { should contain_group(group) } + it { should contain_exec("rvm-system-user-#{username}").with_command("/usr/sbin/dseditgroup -o edit -a #{username} -t user #{group}") } + end +end diff --git a/tools/laptop_puppetisation/modules/rvm/spec/fixtures/hiera.yaml b/tools/laptop_puppetisation/modules/rvm/spec/fixtures/hiera.yaml new file mode 100644 index 00000000..b7f4998e --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/fixtures/hiera.yaml @@ -0,0 +1,11 @@ +--- +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync +:backends: + - rspec + - yaml +:yaml: + :datadir: './spec/fixtures/hieradata' +:hierarchy: + - '%{::clientcert}' + - 'default' diff --git a/tools/laptop_puppetisation/modules/rvm/spec/spec_helper.rb b/tools/laptop_puppetisation/modules/rvm/spec/spec_helper.rb new file mode 100644 index 00000000..d6f2d800 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/spec_helper.rb @@ -0,0 +1,33 @@ +# This file is managed centrally by modulesync +# https://github.com/maestrodev/puppet-modulesync + +require 'puppetlabs_spec_helper/module_spec_helper' + +RSpec.configure do |c| + c.mock_with :rspec + c.hiera_config = File.expand_path(File.join(__FILE__, '../fixtures/hiera.yaml')) + + c.before(:each) do + Puppet::Util::Log.level = :warning + Puppet::Util::Log.newdestination(:console) + end + + c.default_facts = { + :operatingsystem => 'CentOS', + :operatingsystemrelease => '6.6', + :kernel => 'Linux', + :osfamily => 'RedHat', + :architecture => 'x86_64', + :clientcert => 'puppet.acme.com' + }.merge({}) + + c.before do + # avoid "Only root can execute commands as other users" + Puppet.features.stubs(:root? => true) + end +end + +shared_examples :compile, :compile => true do + it { should compile.with_all_deps } +end + diff --git a/tools/laptop_puppetisation/modules/rvm/spec/spec_helper_acceptance.rb b/tools/laptop_puppetisation/modules/rvm/spec/spec_helper_acceptance.rb new file mode 100644 index 00000000..49440b51 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/spec/spec_helper_acceptance.rb @@ -0,0 +1,52 @@ +require 'puppet' +require 'beaker-rspec/spec_helper' +require 'beaker-rspec/helpers/serverspec' + +# overriding puppet installation for the RedHat family distros due to +# puppet breakage >= 3.5 +def install_puppet(host) + host['platform'] =~ /(fedora|el)-(\d+)/ + if host['platform'] =~ /(fedora|el)-(\d+)/ + safeversion = '3.4.2' + platform = $1 + relver = $2 + on host, "rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-#{platform}-#{relver}.noarch.rpm" + on host, "yum install -y puppet-#{safeversion}" + else + super() + end +end + +RSpec.configure do |c| + + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + c.before(:each) do + Puppet::Util::Log.level = :warning + Puppet::Util::Log.newdestination(:console) + end + + c.before :suite do + hosts.each do |host| + unless (ENV['RS_PROVISION'] == 'no' || ENV['BEAKER_provision'] == 'no') + begin + on host, 'puppet --version' + rescue + if host.is_pe? + install_pe + else + install_puppet(host) + end + end + end + + # Install module and dependencies + puppet_module_install(:source => proj_root, :module_name => File.basename(proj_root).gsub(/^puppet-/,'')) + + on host, puppet('module', 'install', 'stahnma-epel', '--version=0.1.0'), { :acceptable_exit_codes => [0,1] } if fact_on(host,'osfamily') == 'RedHat' + on host, puppet('module', 'install', 'puppetlabs-apache', '--version=1.1.0'), { :acceptable_exit_codes => [0,1] } + end + end + +end diff --git a/tools/laptop_puppetisation/modules/rvm/templates/rvmrc.erb b/tools/laptop_puppetisation/modules/rvm/templates/rvmrc.erb new file mode 100644 index 00000000..8ebac6d0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/templates/rvmrc.erb @@ -0,0 +1,12 @@ +<% if @umask and !@umask.empty? -%> +umask <%= @umask %> +<% end -%> +<% if @max_time_flag and !@max_time_flag.to_s.empty? -%> +export rvm_max_time_flag=<%= @max_time_flag %> +<% end -%> +<% if @autoupdate_flag and !@autoupdate_flag.to_s.empty?-%> +rvm_autoupdate_flag=<%= @autoupdate_flag %> +<% end -%> +<% if @silence_path_mismatch_check_flag and !@silence_path_mismatch_check_flag.to_s.empty? -%> +rvm_silence_path_mismatch_check_flag=<%= @silence_path_mismatch_check_flag %> +<%end -%> diff --git a/tools/laptop_puppetisation/modules/rvm/tests/init.pp b/tools/laptop_puppetisation/modules/rvm/tests/init.pp new file mode 100644 index 00000000..e1a19562 --- /dev/null +++ b/tools/laptop_puppetisation/modules/rvm/tests/init.pp @@ -0,0 +1,7 @@ +if $::osfamily == 'RedHat' { + class { 'epel': + before => Class['rvm'], + } +} + +class { 'rvm': } diff --git a/tools/laptop_puppetisation/modules/software/.fixtures.yml b/tools/laptop_puppetisation/modules/software/.fixtures.yml new file mode 100644 index 00000000..ea5c56ef --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/.fixtures.yml @@ -0,0 +1,6 @@ +fixtures: + repositories: + stdlib: "https://github.com/puppetlabs/puppetlabs-stdlib.git" + apt: "https://github.com/puppetlabs/puppetlabs-apt.git" + symlinks: + software: "#{source_dir}" diff --git a/tools/laptop_puppetisation/modules/software/.gitignore b/tools/laptop_puppetisation/modules/software/.gitignore new file mode 100644 index 00000000..b5c6b35c --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +# OS generated files # +###################### +.DS_Store* +Thumbs.db + +# Bundler # +########### +.bundle +Gemfile.lock + +# puppet module build # +####################### +/pkg + +# Librarian Puppet # +#################### +.tmp/ +modules/ + +# Puppet testing # +################## +spec/fixtures/ +.vagrant +coverage/ + +# tmp & log contents # +###################### +/log/* +/tmp/* + +# Never ignore .gitignore/keep files # +# Has to be last to override above # +# Basically for keeping empty dirs # +###################################### +!.gitignore +!.gitkeep diff --git a/tools/laptop_puppetisation/modules/software/.rubocop.yml b/tools/laptop_puppetisation/modules/software/.rubocop.yml new file mode 100644 index 00000000..5f3cc164 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/.rubocop.yml @@ -0,0 +1,48 @@ +# RuboCop config file +# Configure cops +# https://github.com/bbatsov/rubocop +# https://github.com/bbatsov/rubocop/blob/master/config/default.yml +# https://github.com/bbatsov/ruby-style-guide +# + +AllCops: + Include: + - '**/*.gemspec' + - '**/*.rake' + - '**/Gemfile' + - '**/Puppetfile' + - '**/Rakefile' + - '**/Guardfile' + Exclude: + - 'modules/**/*' + - 'pkg/**/*' + - 'spec/fixtures/**/*' + - 'vendor/**/*' + DisplayCopNames: true + +Metrics/MethodLength: + # Ruduce this... Max: 10 + Max: 28 + +Metrics/LineLength: + # Ruduce this... Max: 80 + Max: 111 + +Metrics/AbcSize: + # Ruduce this... Max: 15 + Max: 30 + +Metrics/CyclomaticComplexity: + # Ruduce this... Max: 6 + Max: 8 + +# Cop supports --auto-correct. +# Configuration parameters: SupportedStyles. +# Support ruby 1.8.7 +Style/HashSyntax: + EnforcedStyle: hash_rockets + +# The shebang stuff at the top triggers this +Style/LeadingCommentSpace: + Exclude: + - Puppetfile diff --git a/tools/laptop_puppetisation/modules/software/.ruby-gemset b/tools/laptop_puppetisation/modules/software/.ruby-gemset new file mode 100644 index 00000000..4a1d043b --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/.ruby-gemset @@ -0,0 +1 @@ +puppet-module diff --git a/tools/laptop_puppetisation/modules/software/.travis.yml b/tools/laptop_puppetisation/modules/software/.travis.yml new file mode 100644 index 00000000..0c309c94 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/.travis.yml @@ -0,0 +1,19 @@ +--- +language: ruby +cache: bundler +bundler_args: --without system_tests development +script: "bundle exec rake test SPEC_OPTS='--format documentation'" +sudo: false +matrix: + fast_finish: true + include: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.9 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.9 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" +notifications: + email: false diff --git a/tools/laptop_puppetisation/modules/software/CHANGELOG b/tools/laptop_puppetisation/modules/software/CHANGELOG new file mode 100644 index 00000000..7dab1642 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/CHANGELOG @@ -0,0 +1,59 @@ +2016-08-28 (1.1.0) Chris Edester + * Windows support + * Ubuntu 16.04 support + * Various bug fixes + * Bump versions to latest + +2016-03-12 (1.0.2) Chris Edester + * Bump versions + +2016-03-09 (1.0.1) Chris Edester + * Explicitly set 64-bit for chrome apt repo to avoid error + +2015-08-07 (1.0.0) Chris Edester + * Ubuntu - Use official virtualbox repo for latest version + * Support OS X 10.11 El Capitan + * Bump software versions + +2015-08-07 (0.5.0) Chris Edester + * Allow to specify ensure on atom packages and themes + * Breaking change: You must now specify atom packages and themes as hashes + +2015-08-07 (0.4.2) Chris Edester + * Bug fixes for apm provider + +2015-08-06 (0.4.1) Chris Edester + * Bug fix on Darwin + +2015-08-05 (0.4.0) Chris Edester + * Add spec tests + * Bump software versions + +2015-06-04 (0.3.3) Chris Edester + * Allow to set chrome channel + +2015-06-01 (0.3.2) Chris Edester + * Stop overriding package providers + * lint fixes + +2015-05-18 (0.3.1) Chris Edester + * Add Open Connect for Cisco AnyConnect VPN + * Add Synaptic Package Manager + +2015-05-08 (0.3.0) Chris Edester + * Bug fixes for Ubuntu/apt + * Bug fixes for Atom on Ubuntu + * Use apt ppa for Atom on Ubuntu + * Bug fixes for Atom package provider (apm) + +2015-05-06 (0.3.0-rc1) Chris Edester + * Ubuntu Desktop support + * Add MySQL Workbench + * Add Atom + * Add FileZilla + +2015-04-17 (0.2.1) Chris Edester + * Updated doc and initial public release + +2015-04-15 (0.1.1) Chris Edester + * Move module to its own repository diff --git a/tools/laptop_puppetisation/modules/software/Gemfile b/tools/laptop_puppetisation/modules/software/Gemfile new file mode 100644 index 00000000..0fb1eec7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/Gemfile @@ -0,0 +1,59 @@ +source ENV['GEM_SOURCE'] || 'https://rubygems.org' + +group :unit_tests do + gem 'rubocop', '~> 0.41.2', :require => false if RUBY_VERSION =~ /^1\.9/ + gem 'rubocop', :require => false if RUBY_VERSION =~ /^2\./ + gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-puppet-facts', :require => false + gem 'metadata-json-lint', :require => false + gem 'json', :require => false + gem 'puppet-lint-absolute_classname-check', :require => false + gem 'puppet-lint-absolute_template_path', :require => false + gem 'puppet-lint-alias-check', :require => false + gem 'puppet-lint-appends-check', :require => false + gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false + gem 'puppet-lint-empty_string-check', :require => false + gem 'puppet-lint-file_ensure-check', :require => false + gem 'puppet-lint-file_source_rights-check', :require => false + gem 'puppet-lint-leading_zero-check', :require => false + gem 'puppet-lint-numericvariable', :require => false + gem 'puppet-lint-resource_outside_class-check', :require => false + gem 'puppet-lint-resource_reference_syntax', :require => false + gem 'puppet-lint-spaceship_operator_without_tag-check', :require => false + gem 'puppet-lint-strict_indent-check', :require => false + gem 'puppet-lint-trailing_comma-check', :require => false + gem 'puppet-lint-trailing_newline-check', :require => false + gem 'puppet-lint-undef_in_function-check', :require => false + gem 'puppet-lint-unquoted_string-check', :require => false + gem 'puppet-lint-usascii_format-check', :require => false + gem 'puppet-lint-variable_contains_upcase', :require => false + gem 'puppet-lint-version_comparison-check', :require => false +end + +group :development do + gem 'simplecov', :require => false + gem 'librarian-puppet', :require => false +end + +group :system_tests do + gem 'beaker-rspec', :require => false + gem 'serverspec', :require => false +end + +# json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1 +# if using ruby 1.x +gem 'json_pure', '<= 2.0.1', :require => false if RUBY_VERSION =~ /^1\./ + +if (facterversion = ENV['FACTER_GEM_VERSION']) + gem 'facter', facterversion, :require => false +else + gem 'facter', :require => false +end + +if (puppetversion = ENV['PUPPET_GEM_VERSION']) + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', '~> 3.8', :require => false +end + +# vim:ft=ruby diff --git a/tools/laptop_puppetisation/modules/software/LICENSE b/tools/laptop_puppetisation/modules/software/LICENSE new file mode 100644 index 00000000..9cecc1d4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/tools/laptop_puppetisation/modules/software/README.md b/tools/laptop_puppetisation/modules/software/README.md new file mode 100644 index 00000000..d6c6f62a --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/README.md @@ -0,0 +1,166 @@ +software +============= + +[![Build Status](https://travis-ci.org/edestecd/puppet-software.svg)](https://travis-ci.org/edestecd/puppet-software) +[![Puppet Forge](https://img.shields.io/puppetforge/v/edestecd/software.svg)](https://forge.puppetlabs.com/edestecd/software) +[![Puppet Forge Downloads](https://img.shields.io/puppetforge/dt/edestecd/software.svg)](https://forge.puppetlabs.com/edestecd/software) +[![Puppet Forge Score](https://img.shields.io/puppetforge/f/edestecd/software.svg)](https://forge.puppetlabs.com/edestecd/software/scores) +[![Issue Stats](http://issuestats.com/github/edestecd/puppet-software/badge/pr?style=flat)](http://issuestats.com/github/edestecd/puppet-software) + +####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 software](#setup) + * [What software affects](#what-software-affects) + * [Setup requirements](#setup-requirements) + * [Beginning with software](#beginning-with-software) +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) +7. [Contributors](#contributors) + +##Overview + +Puppet Module to install various Desktop Software + +##Module Description + +The software module provides classes to install many commonly needed Desktop Applications. +Many of these applications require little or no configuration and are mostly Graphical. +This module provides a quick way to get many repetitive apps installed. + +This module currently supports: +* Apple Mac OS X +* Ubuntu Desktop +* Windows + +Other modules exist for many of these applications and I have used some of them +as examples, but I prefer to manage these in one module. +Each application has a class, which you may include separately to install +exactly the applications you desire. + +##Setup + +###What software affects + +only installs apps (OS X) and packages (Ubuntu, Windows) + +###Setup Requirements + +only need to install the module + +###Beginning with software + +Install only Google Chrome browser: + +```puppet +include software::browsers::chrome +``` + +##Usage + +###Install various apps + +```puppet +include software::browsers::chrome +include software::browsers::firefox +include software::database::pgcommander +include software::database::sequelpro +include software::editors::atom +include software::editors::textmate +include software::entertainment::vlc +include software::idesdk::android_studio +include software::idesdk::android_tools +include software::prefpanes::hosts +include software::prefpanes::launchrocket +include software::social::skype +include software::storage::drive +include software::storage::fetch +include software::storage::filezilla +include software::utilities::alfred +include software::utilities::controlplane +include software::utilities::iterm +include software::utilities::onyx +include software::vcsscm::git +include software::vcsscm::sourcetree +include software::virtualization::virtualbox +include software::virtualization::vagrant +include software::webstack::anvil +``` + +###Install everything in the browser group + +```puppet +include software::browsers +``` + +###Install apps with hiera yaml + +```puppet +hiera_include('classes') +``` +```yaml +--- +classes: +- software::browsers::chrome +- software::editors::atom +- software::entertainment::vlc +- software::social::skype + +software::browsers::chrome::channel: stable + +software::editors::atom::packages: + language-puppet: {} + linter: {} + linter-puppet-lint: {} + linter-rubocop: {} +software::editors::atom::themes: + twilight-syntax: {} +software::editors::atom::user: username +``` + +##Reference + +### Classes + +* browsers +* database +* editors +* entertainment +* idesdk +* social +* storage +* utilities +* vcsscm +* virtualization +* webstack + +##Limitations + +Some proprietary software requires licenses. +You may need to pass these license keys and possibly urls to use those classes. + +This module has been built on and tested against Puppet 3.2.4 and higher. +While I am sure other versions work, I have not tested them. + +This module supports modern OS X, Ubuntu, and Windows systems. +This module has been heavily tested on: +* OS X 10.9 Mavericks +* OS X 10.10 Yosemite +* OS X 10.11 El Capitan +* Ubuntu Desktop 14.04 +* Ubuntu Desktop 16.04 +* Windows 10 + +Many classes also support older versions of OS X, Ubuntu, and Windows. + +##Development + +Pull Requests welcome +Please at least make sure ```rake test``` passes. + +##Contributors + +Chris Edester (edestecd) diff --git a/tools/laptop_puppetisation/modules/software/Rakefile b/tools/laptop_puppetisation/modules/software/Rakefile new file mode 100644 index 00000000..63f0ed40 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/Rakefile @@ -0,0 +1,59 @@ +require 'rubygems' if RUBY_VERSION < '1.9.0' +# require 'rubocop/rake_task' +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' +require 'metadata-json-lint/rake_task' + +# RuboCop::RakeTask.new + +exclude_paths = [ + 'modules/**/*', + 'pkg/**/*', + 'spec/**/*', + 'vendor/**/*' +] + +# Puppet-Lint 1.1.0 +Rake::Task[:lint].clear +PuppetLint::RakeTask.new :lint do |config| + config.ignore_paths = exclude_paths + config.disable_checks = %w(class_inherits_from_params_class 80chars) + config.fail_on_warnings = true +end +# Puppet-Lint 1.1.0 as well ... +PuppetLint.configuration.relative = true +PuppetSyntax.exclude_paths = exclude_paths + +Rake::Task[:default].prerequisites.clear +task :default => :all + +desc 'Run RuboCop' +task :rubocop do + sh 'rubocop' +end + +desc 'Clean up modules / pkg' +task :clean do + sh 'rm -rf modules pkg spec/fixtures' +end + +task :success do + puts "\n\e[32mAll tests passing...\e[0m" +end + +desc 'Run all' +task :all => [ + :clean, + :test, + :success +] + +desc 'Run rubocop, syntax, lint, and spec tests' +task :test => [ + :rubocop, + :syntax, + :lint, + :metadata_lint, + :spec +] diff --git a/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/apm.rb b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/apm.rb new file mode 100644 index 00000000..5c9cb080 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/apm.rb @@ -0,0 +1,114 @@ +# lib/puppet/provider/package/apm.rb + +require 'puppet/provider/package' + +Puppet::Type.type(:package).provide(:apm, :parent => Puppet::Provider::Package) do + desc 'Atom packages via `apm`.' + + has_feature :installable, :uninstallable, :upgradeable, :versionable + + commands :apm => 'apm' + + def self.parse(line, user) + if line.chomp =~ / (\S+)@(\d+\.\d+\.\d+)/ + { :name => Regexp.last_match(1), :provider => :apm, + :ensure => Regexp.last_match(2), :source => user } + end + end + + def self.instances_by_user(user) + command = [command(:apm), :list, '--no-color'] + + begin + output = execute(command, command_opts(user)) + [].tap do |a| + output.lines.each do |line| + next unless (package = parse(line, user)) + a << new(package) + end + end.compact + rescue Puppet::ExecutionFailure => e + raise Puppet::Error, "Could not list atom packages: #{e}" + end + end + + def self.instances + Dir.entries(home_prefix).reject { |u| u.start_with?('.') || u.eql?('Shared') }.collect do |user| + instances_by_user(user) + end.flatten + end + + def query + self.class.instances.each do |pkg| + if @resource.name.eql?(pkg.name) && @resource.source.eql?(pkg.source) + return pkg.properties + end + end + nil + end + + def latest + command = [command(:apm), :upgrade, '--list', '--no-color'] + output = execute(command, self.class.command_opts(@resource[:source])) + + if output =~ / #{Regexp.escape @resource[:name]} (\d+\.\d+\.\d+) -> (\d+\.\d+\.\d+)/ + Regexp.last_match(2) + else + @property_hash[:ensure] + end + end + + def install + command = [command(:apm), :install] + + should = @resource.should(:ensure) + command << if [:latest, :installed, :present].include?(should) + @resource[:name] + else + "#{@resource[:name]}@#{should}" + end + + command << '--no-color' + + execute(command, self.class.command_opts(@resource[:source])) + end + + def update + install + end + + def uninstall + command = [command(:apm), :uninstall, @resource[:name], '--no-color'] + execute(command, self.class.command_opts(@resource[:source])) + end + + def self.default_user(user) + user || Facter.value(:id) || 'root' + end + + def self.home(user) + File.join(home_prefix, default_user(user)) + end + + def self.home_prefix + case Facter.value(:kernel) + when 'Darwin' then File.join('', 'Users') + when 'Linux' then File.join('', 'home') + else + raise 'unsupported' + end + end + + def self.command_opts(user) + Dir.chdir(home(user).to_s) + @command_opts ||= { + :combine => true, + :custom_environment => { + 'HOME' => home(user).to_s, + 'PATH' => '/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin' + }, + :failonfail => true, + :uid => default_user(user) + } + end +end diff --git a/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/appcompressed.rb b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/appcompressed.rb new file mode 100644 index 00000000..520df7a4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/appcompressed.rb @@ -0,0 +1,100 @@ +# lib/puppet/provider/package/appcompressed.rb + +require 'puppet/provider/package' +Puppet::Type.type(:package).provide(:appcompressed, :parent => Puppet::Provider::Package) do + desc 'Installs a compressed .app. Supports zip, tar.gz, tar.bz2' + + FLAVORS = %w(zip tgz tar.gz tbz tbz2 tar.bz2).freeze + + confine :operatingsystem => :darwin + + commands :curl => '/usr/bin/curl' + commands :ditto => '/usr/bin/ditto' + commands :tar => '/usr/bin/tar' + # commands :rm => '/bin/rm' + + # JJM We store a cookie for each installed .app.compressed in /var/db + def self.instances_by_name + # Allow this gross code.... + # rubocop:disable Style/BlockDelimiters, Style/MultilineBlockChain + Dir.entries('/var/db').find_all { |f| + f =~ /^\.puppet_appcompressed_installed_/ + }.collect do |f| + name = f.sub(/^\.puppet_appcompressed_installed_/, '') + yield name if block_given? + name + end + # rubocop:enable Style/BlockDelimiters, Style/MultilineBlockChain + end + + def self.instances + instances_by_name.collect do |name| + new(:name => name, :provider => :appcompressed, :ensure => :installed) + end + end + + def query + return unless File.exist?(receipt_path) + { + :name => @resource[:name], + :ensure => :installed + } + end + + def install + raise('Mac OS X compressed apps must specify a package name') unless @resource[:name] + raise('Mac OS X compressed apps must specify a package source') unless @resource[:source] + raise("Unknown flavor #{flavor}") unless FLAVORS.include?(flavor) + + cached_source = @resource[:source] + tmpdir = Dir.mktmpdir + begin + if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source + cached_source = File.join(tmpdir, @resource[:name]) + curl '-o', cached_source, '-C', '-', '-L', '-s', '--url', @resource[:source] + Puppet.debug "Success: curl transfered [#{@resource[:name]}]" + end + + # rm "-rf", app_path + + case flavor + when 'zip' + # unzip cached_source, "-d", "/Applications" + ditto '-xk', cached_source, '/Applications' + when 'tar.gz', 'tgz' + tar '-zxf', cached_source, '-C', '/Applications' + when 'tar.bz2', 'tbz', 'tbz2' + tar '-jxf', cached_source, '-C', '/Applications' + else + raise "Can't decompress flavor #{flavor}" + end + + File.open(receipt_path, 'w') do |t| + t.print "name: '#{@resource[:name]}'\n" + t.print "source: '#{@resource[:source]}'\n" + end + ensure + FileUtils.remove_entry_secure(tmpdir, true) + end + end + + # def uninstall + # rm "-rf", app_path + # rm "-f", receipt_path + # end + + private + + def flavor + @resource[:flavor] || @resource[:source].match(/\.(#{FLAVORS.join('|')})$/i) { |m| m[1] } + end + + # This is not always correct... + def app_path + "/Applications/#{@resource[:name]}.app" + end + + def receipt_path + "/var/db/.puppet_appcompressed_installed_#{@resource[:name]}" + end +end diff --git a/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/prefpanecompressed.rb b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/prefpanecompressed.rb new file mode 100644 index 00000000..ac93b802 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/lib/puppet/provider/package/prefpanecompressed.rb @@ -0,0 +1,100 @@ +# lib/puppet/provider/package/prefpanecompressed.rb + +require 'puppet/provider/package' +Puppet::Type.type(:package).provide(:prefpanecompressed, :parent => Puppet::Provider::Package) do + desc 'Installs a compressed .prefPane. Supports zip, tar.gz, tar.bz2' + + FLAVORZ = %w(zip tgz tar.gz tbz tbz2 tar.bz2).freeze + + confine :operatingsystem => :darwin + + commands :curl => '/usr/bin/curl' + commands :ditto => '/usr/bin/ditto' + commands :tar => '/usr/bin/tar' + # commands :rm => '/bin/rm' + + # JJM We store a cookie for each installed .app.compressed in /var/db + def self.instances_by_name + # Allow this gross code.... + # rubocop:disable Style/BlockDelimiters, Style/MultilineBlockChain + Dir.entries('/var/db').find_all { |f| + f =~ /^\.puppet_prefpanecompressed_installed_/ + }.collect do |f| + name = f.sub(/^\.puppet_prefpanecompressed_installed_/, '') + yield name if block_given? + name + end + # rubocop:enable Style/BlockDelimiters, Style/MultilineBlockChain + end + + def self.instances + instances_by_name.collect do |name| + new(:name => name, :provider => :prefpanecompressed, :ensure => :installed) + end + end + + def query + return unless File.exist?(receipt_path) + { + :name => @resource[:name], + :ensure => :installed + } + end + + def install + raise('Mac OS X compressed prefPanes must specify a package name') unless @resource[:name] + raise('Mac OS X compressed prefPanes must specify a package source') unless @resource[:source] + raise("Unknown flavor #{flavor}") unless FLAVORZ.include?(flavor) + + cached_source = @resource[:source] + tmpdir = Dir.mktmpdir + begin + if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source + cached_source = File.join(tmpdir, @resource[:name]) + curl '-o', cached_source, '-C', '-', '-L', '-s', '--url', @resource[:source] + Puppet.debug "Success: curl transfered [#{@resource[:name]}]" + end + + # rm '-rf', pane_path + + case flavor + when 'zip' + # unzip cached_source, '-d', '/Library/PreferencePanes' + ditto '-xk', cached_source, '/Library/PreferencePanes' + when 'tar.gz', 'tgz' + tar '-zxf', cached_source, '-C', '/Library/PreferencePanes' + when 'tar.bz2', 'tbz', 'tbz2' + tar '-jxf', cached_source, '-C', '/Library/PreferencePanes' + else + raise "Can't decompress flavor #{flavor}" + end + + File.open(receipt_path, 'w') do |t| + t.print "name: '#{@resource[:name]}'\n" + t.print "source: '#{@resource[:source]}'\n" + end + ensure + FileUtils.remove_entry_secure(tmpdir, true) + end + end + + # def uninstall + # rm '-rf', pane_path + # rm '-f', receipt_path + # end + + private + + def flavor + @resource[:flavor] || @resource[:source].match(/\.(#{FLAVORZ.join('|')})$/i) { |m| m[1] } + end + + # This is not always correct... + def pane_path + "/Library/PreferencePanes/#{@resource[:name]}.prefPane" + end + + def receipt_path + "/var/db/.puppet_prefpanecompressed_installed_#{@resource[:name]}" + end +end diff --git a/tools/laptop_puppetisation/modules/software/manifests/browsers.pp b/tools/laptop_puppetisation/modules/software/manifests/browsers.pp new file mode 100644 index 00000000..84f37b03 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/browsers.pp @@ -0,0 +1,28 @@ +# browsers.pp +# +# browsers group +# Mainly web browsers and plugins +# +# + +class software::browsers ( + $ensure = $software::params::software_ensure, + $chrome_url = $software::params::chrome_url, + $chrome_channel = $software::params::chrome_channel, + $firefox_version = $software::params::firefox_version, + $firefox_url = $software::params::firefox_url, +) inherits software::params { + + class { '::software::browsers::chrome': + ensure => $ensure, + url => $chrome_url, + channel => $chrome_channel, + } + + class { '::software::browsers::firefox': + ensure => $ensure, + version => $firefox_version, + url => $firefox_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/browsers/chrome.pp b/tools/laptop_puppetisation/modules/software/manifests/browsers/chrome.pp new file mode 100644 index 00000000..56db25c0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/browsers/chrome.pp @@ -0,0 +1,63 @@ +# chrome.pp +# Install Google Chrome for OS X, Ubuntu, or Windows +# https://www.google.com/chrome/browser/desktop +# https://www.google.com/linuxrepositories +# + +class software::browsers::chrome ( + $ensure = $software::params::software_ensure, + $url = $software::params::chrome_url, + $channel = $software::params::chrome_channel, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($url) + + package { 'GoogleChrome': + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + validate_string($url) + validate_string($channel) + + $apt_source_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::source { 'google-chrome': + ensure => $apt_source_ensure, + location => $url, + release => 'stable', + repos => 'main', + key => { + 'id' => '4CCA1EAF950CEE4AB83976DCA040830F7FAC5991', + 'source' => 'https://dl.google.com/linux/linux_signing_key.pub', + }, + architecture => 'amd64', + } -> Class['apt::update'] -> + + package { "google-chrome-${channel}": + ensure => $ensure, + } + } + 'windows': { + package { 'googlechrome': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/browsers/firefox.pp b/tools/laptop_puppetisation/modules/software/manifests/browsers/firefox.pp new file mode 100644 index 00000000..a0e5a5ac --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/browsers/firefox.pp @@ -0,0 +1,41 @@ +# firefox.pp +# Install Firefox for OS X, Ubuntu, or Windows +# http://www.mozilla.org/en-US/firefox/new +# + +class software::browsers::firefox ( + $ensure = $software::params::software_ensure, + $version = $software::params::firefox_version, + $url = $software::params::firefox_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Firefox-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + package { 'firefox': + ensure => $ensure, + } + } + 'windows': { + package { 'firefox': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/database.pp b/tools/laptop_puppetisation/modules/software/manifests/database.pp new file mode 100644 index 00000000..6751a929 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/database.pp @@ -0,0 +1,36 @@ +# database.pp +# +# database group +# Mainly graphical database editors for MySQL and PostgreSQL +# +# + +class software::database ( + $ensure = $software::params::software_ensure, + $mysqlworkbench_version = $software::params::mysqlworkbench_version, + $mysqlworkbench_url = $software::params::mysqlworkbench_url, + $pgcommander_version = $software::params::pgcommander_version, + $pgcommander_url = $software::params::pgcommander_url, + $sequelpro_version = $software::params::sequelpro_version, + $sequelpro_url = $software::params::sequelpro_url, +) inherits software::params { + + class { '::software::database::mysqlworkbench': + ensure => $ensure, + version => $mysqlworkbench_version, + url => $mysqlworkbench_url, + } + + class { '::software::database::pgcommander': + ensure => $ensure, + version => $pgcommander_version, + url => $pgcommander_url, + } + + class { '::software::database::sequelpro': + ensure => $ensure, + version => $sequelpro_version, + url => $sequelpro_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/database/mysqlworkbench.pp b/tools/laptop_puppetisation/modules/software/manifests/database/mysqlworkbench.pp new file mode 100644 index 00000000..cadbc9db --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/database/mysqlworkbench.pp @@ -0,0 +1,43 @@ +# mysqlworkbench.pp +# Install MySQL Workbench for OS X, Ubuntu, or Windows +# https://www.mysql.com/products/workbench +# https://dev.mysql.com/downloads/workbench +# + +class software::database::mysqlworkbench ( + $ensure = $software::params::software_ensure, + $version = $software::params::mysqlworkbench_version, + $url = $software::params::mysqlworkbench_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "MySQLWorkbench-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + package { 'mysql-workbench': + ensure => $ensure, + } + } + 'windows': { + package { 'mysql.workbench': + ensure => $ensure, + provider => chocolatey, + install_options => ['--allow-empty-checksums'], + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/database/pgcommander.pp b/tools/laptop_puppetisation/modules/software/manifests/database/pgcommander.pp new file mode 100644 index 00000000..94fa1179 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/database/pgcommander.pp @@ -0,0 +1,33 @@ +# pgcommander.pp +# Install PG Commander for OS X +# https://eggerapps.at/pgcommander +# +# The next version (in beta currently): +# https://eggerapps.at/postico +# + +class software::database::pgcommander ( + $ensure = $software::params::software_ensure, + $version = $software::params::pgcommander_version, + $url = $software::params::pgcommander_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "PGCommander-${version}": + ensure => $ensure, + provider => appcompressed, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/database/sequelpro.pp b/tools/laptop_puppetisation/modules/software/manifests/database/sequelpro.pp new file mode 100644 index 00000000..d6fc66c0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/database/sequelpro.pp @@ -0,0 +1,30 @@ +# sequelpro.pp +# Install Sequel Pro for OS X +# http://www.sequelpro.com +# + +class software::database::sequelpro ( + $ensure = $software::params::software_ensure, + $version = $software::params::sequelpro_version, + $url = $software::params::sequelpro_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Sequel-Pro-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/drivers.pp b/tools/laptop_puppetisation/modules/software/manifests/drivers.pp new file mode 100644 index 00000000..509ce72f --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/drivers.pp @@ -0,0 +1,20 @@ +# drivers.pp +# +# drivers group +# Install printer etc. drivers +# +# + +class software::drivers ( + $ensure = $software::params::software_ensure, + $lanier_mpc5503_version = $software::params::lanier_mpc5503_version, + $lanier_mpc5503_url = $software::params::lanier_mpc5503_url, +) inherits software::params { + + class { '::software::drivers::lanier_mpc5503': + ensure => $ensure, + version => $lanier_mpc5503_version, + url => $lanier_mpc5503_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/drivers/lanier_mpc5503.pp b/tools/laptop_puppetisation/modules/software/manifests/drivers/lanier_mpc5503.pp new file mode 100644 index 00000000..e91d2332 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/drivers/lanier_mpc5503.pp @@ -0,0 +1,53 @@ +# lanier_mpc5503.pp +# Install Lanier MP C5503 drivers for OS X +# +# Apple all in one: +# http://support.apple.com/downloads/ +# Lanier Site (specific to printer only): +# http://www.lanier.com/downloads/Default.aspx?hbn=drivers +# + +class software::drivers::lanier_mpc5503 ( + $ensure = $software::params::software_ensure, + $version = $software::params::lanier_mpc5503_version, + $url = $software::params::lanier_mpc5503_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + $printer_ensure = $ensure ? { + 'installed' => present, + default => $ensure, + } + + package { "Lanier-MPC5503-${version}": + ensure => $ensure, + provider => pkgdmg, + source => $url, + } -> + + printer { 'BIO-PBD009-mpc5503': + ensure => $printer_ensure, + enabled => true, + uri => 'smb://kepler.it.muohio.edu/BIO-PBD009-mpc5503', + location => 'PBD009', + ppd => '/Library/Printers/PPDs/Contents/Resources/LANIER MP C5503', + shared => false, + #options => { }, + ppd_options => { + 'OptionTray' => 'LCT', + 'Finisher' => 'FinVOLGABBK', + }, # *Finisher FinVOLGABBK/Finisher SR3170: "" + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/editors.pp b/tools/laptop_puppetisation/modules/software/manifests/editors.pp new file mode 100644 index 00000000..18529d8e --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/editors.pp @@ -0,0 +1,36 @@ +# editors.pp +# +# editors group +# Mainly text editors +# +# + +class software::editors ( + $ensure = $software::params::software_ensure, + $atom_url = $software::params::atom_url, + $textmate_url = $software::params::textmate_url, + $textwrangler_version = $software::params::textwrangler_version, + $textwrangler_url = $software::params::textwrangler_url, +) inherits software::params { + + class { '::software::editors::atom': + ensure => $ensure, + url => $atom_url, + } + + class { '::software::editors::textmate': + ensure => $ensure, + url => $textmate_url, + } + + class { '::software::editors::textwrangler': + ensure => $ensure, + version => $textwrangler_version, + url => $textwrangler_url, + } + + class { '::software::editors::vim': + ensure => $ensure, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/editors/atom.pp b/tools/laptop_puppetisation/modules/software/manifests/editors/atom.pp new file mode 100644 index 00000000..018ee961 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/editors/atom.pp @@ -0,0 +1,97 @@ +# atom.pp +# Install Atom, GitHub's text editor +# https://atom.io +# +# Gets the latest release version... +# + +class software::editors::atom ( + $ensure = $software::params::software_ensure, + $url = $software::params::atom_url, + $packages = {}, + $themes = {}, + $user = undef, +) inherits software::params { + + validate_string($ensure) + validate_hash($packages, $themes) + + unless empty(merge($packages, $themes)) { + validate_string($user) + } + + case $::operatingsystem { + 'Darwin': { + validate_string($url) + $apm_require = File['/usr/local/bin/apm'] + + package { 'Atom': + ensure => $ensure, + provider => appcompressed, + flavor => zip, + source => $url, + } + + ensure_resource('file', '/usr/local/bin', { + ensure => directory, + require => Package['Atom'], + }) + + file { '/usr/local/bin/apm': + ensure => link, + target => '/Applications/Atom.app/Contents/Resources/app/apm/node_modules/.bin/apm', + mode => '0755', + } -> + + file { '/usr/local/bin/atom': + ensure => link, + target => '/Applications/Atom.app/Contents/Resources/app/atom.sh', + mode => '0755', + } + } + 'Ubuntu': { + validate_string($url) + $apm_require = Package['atom'] + $apt_ppa_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::ppa { 'ppa:webupd8team/atom': + ensure => $apt_ppa_ensure, + package_manage => true, + } -> Class['apt::update'] -> + + package { 'atom': + ensure => $ensure, + } + } + 'windows': { + package { 'atom': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + + $apm_ensure = $ensure ? { + 'installed' => latest, + default => $ensure, + } + + # strict indent is wrong here... + # lint:ignore:strict_indent + create_resources('package', merge($packages, $themes), { + ensure => $apm_ensure, + provider => apm, + source => $user, + require => $apm_require, + }) + # lint:endignore + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/editors/textmate.pp b/tools/laptop_puppetisation/modules/software/manifests/editors/textmate.pp new file mode 100644 index 00000000..6d1deedb --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/editors/textmate.pp @@ -0,0 +1,31 @@ +# textmate.pp +# Install TextMate 2 for OS X +# http://macromates.com +# +# Gets the latest release version... +# + +class software::editors::textmate ( + $ensure = $software::params::software_ensure, + $url = $software::params::textmate_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($url) + + package { 'TextMate': + ensure => $ensure, + provider => appcompressed, + flavor => tbz, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/editors/textwrangler.pp b/tools/laptop_puppetisation/modules/software/manifests/editors/textwrangler.pp new file mode 100644 index 00000000..a992e2c0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/editors/textwrangler.pp @@ -0,0 +1,30 @@ +# textwrangler.pp +# Install TextWrangler for OS X +# http://www.barebones.com/products/textwrangler +# + +class software::editors::textwrangler ( + $ensure = $software::params::software_ensure, + $version = $software::params::textwrangler_version, + $url = $software::params::textwrangler_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "TextWrangler-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/editors/vim.pp b/tools/laptop_puppetisation/modules/software/manifests/editors/vim.pp new file mode 100644 index 00000000..9a508a16 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/editors/vim.pp @@ -0,0 +1,28 @@ +# vim.pp +# Install VI Improved +# + +class software::editors::vim ( + $ensure = $software::params::software_ensure, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Ubuntu': { + package { 'vim': + ensure => $ensure, + } + } + 'windows': { + package { 'vim': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/entertainment.pp b/tools/laptop_puppetisation/modules/software/manifests/entertainment.pp new file mode 100644 index 00000000..a59060bd --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/entertainment.pp @@ -0,0 +1,23 @@ +# entertainment.pp +# +# entertainment group +# Mainly: +# Video Players +# Music Players +# Games +# +# + +class software::entertainment ( + $ensure = $software::params::software_ensure, + $vlc_version = $software::params::vlc_version, + $vlc_url = $software::params::vlc_url, +) inherits software::params { + + class { '::software::entertainment::vlc': + ensure => $ensure, + version => $vlc_version, + url => $vlc_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/entertainment/vlc.pp b/tools/laptop_puppetisation/modules/software/manifests/entertainment/vlc.pp new file mode 100644 index 00000000..5287a628 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/entertainment/vlc.pp @@ -0,0 +1,41 @@ +# vlc.pp +# Install VideoLAN Media Player +# http://www.videolan.org/vlc/index.html +# + +class software::entertainment::vlc ( + $ensure = $software::params::software_ensure, + $version = $software::params::vlc_version, + $url = $software::params::vlc_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "VLC-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + package { 'vlc': + ensure => $ensure, + } + } + 'windows': { + package { 'vlc': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/idesdk.pp b/tools/laptop_puppetisation/modules/software/manifests/idesdk.pp new file mode 100644 index 00000000..29edaff5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/idesdk.pp @@ -0,0 +1,26 @@ +# idesdk.pp +# +# idesdk group +# Mainly: +# Integrated Development Environment +# Software Development Kit +# +# + +class software::idesdk ( + $ensure = $software::params::software_ensure, + $android_studio_version = $software::params::android_studio_version, + $android_studio_url = $software::params::android_studio_url, +) inherits software::params { + + class { '::software::idesdk::android_studio': + ensure => $ensure, + version => $android_studio_version, + url => $android_studio_url, + } + + class { '::software::idesdk::android_tools': + ensure => $ensure, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_studio.pp b/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_studio.pp new file mode 100644 index 00000000..971631f1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_studio.pp @@ -0,0 +1,36 @@ +# android_studio.pp +# Install Android Studio for OS X or Windows +# https://developer.android.com/sdk/index.html +# + +class software::idesdk::android_studio ( + $ensure = $software::params::software_ensure, + $version = $software::params::android_studio_version, + $url = $software::params::android_studio_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Android-Studio-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'windows': { + package { 'androidstudio': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_tools.pp b/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_tools.pp new file mode 100644 index 00000000..fcd96aa7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/idesdk/android_tools.pp @@ -0,0 +1,29 @@ +# android_tools.pp +# Install Android Tools +# adb and fastboot command line tools +# + +class software::idesdk::android_tools ( + $ensure = $software::params::software_ensure, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Ubuntu': { + package { ['android-tools-adb', 'android-tools-fastboot']: + ensure => $ensure, + } + } + 'windows': { + package { 'adb': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/init.pp b/tools/laptop_puppetisation/modules/software/manifests/init.pp new file mode 100644 index 00000000..2be55a3b --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/init.pp @@ -0,0 +1,23 @@ +# init.pp +# Main class of software +# +# +# Install Generic Software on OS X +# Organized into individual packages and groups. +# Most of these are Graphical apps that require little/no configuration. +# They are just simple Download and place apps. +# +# + +class software ( + $applications_path = $software::params::applications_path, + $preference_panes_path = $software::params::preference_panes_path, + $utilities_path = $software::params::utilities_path, +) inherits software::params { + + # Not Used + fail("The ${module_name} module does not use the ${name} class. + Just include the software or group classes you want like this: + include software::browsers::chrome (just chrome) include software::browsers (all browsers in group)") + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/params.pp b/tools/laptop_puppetisation/modules/software/manifests/params.pp new file mode 100644 index 00000000..0bd10249 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/params.pp @@ -0,0 +1,164 @@ +# params.pp +# Set up Software parameters defaults etc. +# For osx software +# + +class software::params ( + $ensure = getvar('::software-ensure'), +) { + + # At least OSX 10.8 "Mountain Lion" + if ($::operatingsystem == 'Darwin') and (versioncmp($::macosx_productversion, '10.8') >= 0) { + #### init #### + $software_ensure = $ensure ? { + undef => installed, + default => $ensure, + } + $applications_path = '/Applications' + $utilities_path = "${applications_path}/Utilities" + $preference_panes_path = '/Library/PreferencePanes' + + + #### browsers #### + $chrome_url = 'https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg' + $firefox_version = '48.0' + $firefox_url = "https://download-installer.cdn.mozilla.net/pub/firefox/releases/${firefox_version}/mac/en-US/Firefox%20${firefox_version}.dmg" + + + #### database #### + $mysqlworkbench_version = '6.3.7' + $mysqlworkbench_url = "http://cdn.mysql.com/Downloads/MySQLGUITools/mysql-workbench-community-${mysqlworkbench_version}-osx-x86_64.dmg" + $pgcommander_version = '1.5.9' + $pgcommander_url = "https://eggerapps-downloads.s3.amazonaws.com/pgcommander-${pgcommander_version}.zip" + $sequelpro_version = '1.1.2' + $sequelpro_url = "https://github.com/sequelpro/sequelpro/releases/download/release-${sequelpro_version}/sequel-pro-${sequelpro_version}.dmg" + + #### drivers #### + $lanier_mpc5503_version = '2.2.0.0' + $lanier_mpc5503_url = "http://support.ricoh.com/bb/pub_e/dr_ut_e/0001269/0001269425/V2200/LANIER_PS_Printers_Vol3_EXP_LIO_${lanier_mpc5503_version}.dmg" + + + #### editors #### + $atom_url = 'https://atom.io/download/mac' + $textmate_url = 'https://api.textmate.org/downloads/release' + $textwrangler_version = '5.5.1' + $textwrangler_url = "https://s3.amazonaws.com/BBSW-download/TextWrangler_${textwrangler_version}.dmg" + + + #### entertainment #### + $vlc_version = '2.2.4' + $vlc_url = "https://get.videolan.org/vlc/${vlc_version}/macosx/vlc-${vlc_version}.dmg" + + + #### idesdk #### + $android_studio_version = '143.2915827' + $android_studio_url = "https://dl.google.com/dl/android/studio/install/2.1.2.0/android-studio-ide-${android_studio_version}-mac.dmg" + + + #### prefpanes #### + $hosts_version = '1.3' + $hosts_url = "https://github.com/downloads/specialunderwear/Hosts.prefpane/Hosts-${hosts_version}.pkg" + $launchrocket_version = '0.7' + $launchrocket_url = "https://github.com/jimbojsb/launchrocket/releases/download/v${launchrocket_version}/LaunchRocket.prefPane.zip" + + + #### social #### + $skype_version = '7.33.206' + $skype_url = "http://download.skype.com/macosx/59bb2e5bac07f54c8d4ade192fa36d1c/Skype_${skype_version}.dmg" + + + #### storage #### + $drive_url = 'https://dl.google.com/drive/installgoogledrive.dmg' + $fetch_version = '5.7.5' + $fetch_url = "http://getfetch.com/Fetch_${fetch_version}.dmg" + $filezilla_version = '3.20.1' + $filezilla_url = "https://sourceforge.net/projects/filezilla/files/FileZilla_Client/${filezilla_version}/FileZilla_${filezilla_version}_macosx-x86.app.tar.bz2/download" + + + #### utilities #### + $alfred_version = '3.0.3_694' + $alfred_url = "https://cachefly.alfredapp.com/Alfred_${alfred_version}.zip" + $controlplane_version = '1.6.4' + $controlplane_url = "https://dl.dropboxusercontent.com/u/12850/ControlPlane/ControlPlane-${controlplane_version}.dmg" + $iterm_version = '3_0_7' + $iterm_url = "https://iterm2.com/downloads/stable/iTerm2-${iterm_version}.zip" + + + #### vcsscm #### + $sourcetree_version = '2.3.1' + $sourcetree_url = "https://downloads.atlassian.com/software/sourcetree/SourceTree_${sourcetree_version}.zip" + + + #### virtualization #### + $virtualbox_version = '5.1.4' + $virtualbox_build = '110228' + $virtualbox_url = "http://download.virtualbox.org/virtualbox/${virtualbox_version}/VirtualBox-${virtualbox_version}-${virtualbox_build}-OSX.dmg" + + + #### webstack #### + $anvil_url = 'http://s3.amazonaws.com/sparkler_versions/versions/uploads/000/000/129/original/Anvil_2016-02-24_11-50-56.zip' + $pow_url = 'get.pow.cx' + + + if versioncmp($::macosx_productversion_major, '10.8') == 0 { + #### utilities #### + $onyx_url = 'http://www.titanium.free.fr/download/108/OnyX.dmg' + } elsif versioncmp($::macosx_productversion_major, '10.9') == 0 { + #### utilities #### + $onyx_url = 'http://www.titanium.free.fr/download/109/OnyX.dmg' + } elsif versioncmp($::macosx_productversion_major, '10.10') == 0 { + #### utilities #### + $onyx_url = 'http://www.titanium.free.fr/download/1010/OnyX.dmg' + } elsif versioncmp($::macosx_productversion_major, '10.11') == 0 { + #### utilities #### + $onyx_url = 'http://joel.barriere.pagesperso-orange.fr/download/1011/OnyX.dmg' + } elsif versioncmp($::macosx_productversion_major, '10.12') == 0 { + #### utilities #### + $onyx_url = 'http://joel.barriere.pagesperso-orange.fr/download/1012/OnyX.dmg' + } else { + fail("The ${module_name} module only supports 'Mountain Lion', 'Mavericks', 'Yosemite', 'El Capitan', 'Sierra'.") + } + } elsif ($::operatingsystem == 'Ubuntu') and (versioncmp($::operatingsystemrelease, '12.04') >= 0) { + #### init #### + $software_ensure = $ensure ? { + undef => latest, + default => $ensure, + } + + + #### browsers #### + $chrome_url = 'http://dl.google.com/linux/chrome/deb/' + $chrome_channel = 'stable' + + + #### editors #### + $atom_url = 'https://atom.io/download/deb' + + + #### virtualization #### + $virtualbox_version = '5.1' + $virtualbox_build = '110228' + $virtualbox_url = 'http://download.virtualbox.org/virtualbox/debian' + if versioncmp($::operatingsystemrelease, '16.04') >= 0 { + $virtualbox_key = { + 'id' => 'B9F8D658297AF3EFC18D5CDFA2F683C52980AECF', + 'source' => 'https://www.virtualbox.org/download/oracle_vbox_2016.asc', + } + } else { + $virtualbox_key = { + 'id' => '7B0FAB3A13B907435925D9C954422A4B98AB5139', + 'source' => 'https://www.virtualbox.org/download/oracle_vbox.asc', + } + } + } elsif ($::operatingsystem == 'windows') and (versioncmp($::operatingsystemrelease, '7.0') >= 0) { + #### init #### + include '::chocolatey' + $software_ensure = $ensure ? { + undef => latest, + default => $ensure, + } + } else { + fail("The ${module_name} module is not supported on ${::operatingsystem} with version ${::operatingsystemrelease}.") + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/prefpanes.pp b/tools/laptop_puppetisation/modules/software/manifests/prefpanes.pp new file mode 100644 index 00000000..b2fd51ea --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/prefpanes.pp @@ -0,0 +1,28 @@ +# prefpanes.pp +# +# prefpanes group +# Add System Preferences Preference Panes +# +# + +class software::prefpanes ( + $ensure = $software::params::software_ensure, + $hosts_version = $software::params::hosts_version, + $hosts_url = $software::params::hosts_url, + $launchrocket_version = $software::params::launchrocket_version, + $launchrocket_url = $software::params::launchrocket_url, +) inherits software::params { + + class { '::software::prefpanes::hosts': + ensure => $ensure, + version => $hosts_version, + url => $hosts_url, + } + + class { '::software::prefpanes::launchrocket': + ensure => $ensure, + version => $launchrocket_version, + url => $launchrocket_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/prefpanes/hosts.pp b/tools/laptop_puppetisation/modules/software/manifests/prefpanes/hosts.pp new file mode 100644 index 00000000..5cfdcc92 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/prefpanes/hosts.pp @@ -0,0 +1,30 @@ +# hosts.pp +# Install specialunderwear/Hosts.prefpane for OS X +# https://github.com/specialunderwear/Hosts.prefpane +# + +class software::prefpanes::hosts ( + $ensure = $software::params::software_ensure, + $version = $software::params::hosts_version, + $url = $software::params::hosts_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Hosts-${version}": + ensure => $ensure, + provider => pkgdmg, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/prefpanes/launchrocket.pp b/tools/laptop_puppetisation/modules/software/manifests/prefpanes/launchrocket.pp new file mode 100644 index 00000000..444e0d3a --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/prefpanes/launchrocket.pp @@ -0,0 +1,30 @@ +# launchrocket.pp +# Install jimbojsb/launchrocket for OS X +# https://github.com/jimbojsb/launchrocket +# + +class software::prefpanes::launchrocket ( + $ensure = $software::params::software_ensure, + $version = $software::params::launchrocket_version, + $url = $software::params::launchrocket_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "LaunchRocket-${version}": + ensure => $ensure, + provider => prefpanecompressed, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/social.pp b/tools/laptop_puppetisation/modules/software/manifests/social.pp new file mode 100644 index 00000000..e39fb6d7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/social.pp @@ -0,0 +1,20 @@ +# social.pp +# +# social group +# Chat/Messaging +# +# + +class software::social ( + $ensure = $software::params::software_ensure, + $skype_version = $software::params::skype_version, + $skype_url = $software::params::skype_url, +) inherits software::params { + + class { '::software::social::skype': + ensure => $ensure, + version => $skype_version, + url => $skype_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/social/skype.pp b/tools/laptop_puppetisation/modules/software/manifests/social/skype.pp new file mode 100644 index 00000000..430b3603 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/social/skype.pp @@ -0,0 +1,55 @@ +# skype.pp +# Install Skype for OS X, Ubuntu, or Windows +# http://www.skype.com/en +# + +class software::social::skype ( + $ensure = $software::params::software_ensure, + $version = $software::params::skype_version, + $url = $software::params::skype_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Skype-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + $apt_source_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::source { 'skype-partner': + ensure => $apt_source_ensure, + location => 'http://archive.canonical.com/ubuntu', + repos => 'partner', + include_src => false, + } -> Class['apt::update'] -> + + package { 'skype': + ensure => $ensure, + } + } + 'windows': { + package { 'skype': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/storage.pp b/tools/laptop_puppetisation/modules/software/manifests/storage.pp new file mode 100644 index 00000000..a027d701 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/storage.pp @@ -0,0 +1,35 @@ +# storage.pp +# +# storage group +# File Storage apps.. +# FTP/SFTP and Cloud Storage +# +# + +class software::storage ( + $ensure = $software::params::software_ensure, + $drive_url = $software::params::drive_url, + $fetch_version = $software::params::fetch_version, + $fetch_url = $software::params::fetch_url, + $filezilla_version = $software::params::filezilla_version, + $filezilla_url = $software::params::filezilla_url, +) inherits software::params { + + class { '::software::storage::drive': + ensure => $ensure, + url => $drive_url, + } + + class { '::software::storage::fetch': + ensure => $ensure, + version => $fetch_version, + url => $fetch_url, + } + + class { '::software::storage::filezilla': + ensure => $ensure, + version => $filezilla_version, + url => $filezilla_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/storage/drive.pp b/tools/laptop_puppetisation/modules/software/manifests/storage/drive.pp new file mode 100644 index 00000000..bfd84d21 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/storage/drive.pp @@ -0,0 +1,56 @@ +# drive.pp +# Install Google Drive for OS X, Ubuntu, or Windows +# https://www.google.com/drive/download +# +# Some third party solutions exist for linux +# http://www.howtogeek.com/196635/an-official-google-drive-for-linux-is-here-sort-of-maybe-this-is-all-well-ever-get +# I choose the most official command line solution: +# https://github.com/odeke-em/drive +# + +class software::storage::drive ( + $ensure = $software::params::software_ensure, + $url = $software::params::drive_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($url) + + package { 'GoogleDrive': + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + 'Ubuntu': { + $apt_ppa_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::ppa { 'ppa:twodopeshaggy/drive': + ensure => $apt_ppa_ensure, + package_manage => true, + } -> Class['apt::update'] -> + + package { 'drive': + ensure => $ensure, + } + } + 'windows': { + package { 'googledrive': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/storage/fetch.pp b/tools/laptop_puppetisation/modules/software/manifests/storage/fetch.pp new file mode 100644 index 00000000..3cb69ef8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/storage/fetch.pp @@ -0,0 +1,30 @@ +# fetch.pp +# Install Fetch for OS X +# http://fetchsoftworks.com +# + +class software::storage::fetch ( + $ensure = $software::params::software_ensure, + $version = $software::params::fetch_version, + $url = $software::params::fetch_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "Fetch-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/storage/filezilla.pp b/tools/laptop_puppetisation/modules/software/manifests/storage/filezilla.pp new file mode 100644 index 00000000..cf0b2991 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/storage/filezilla.pp @@ -0,0 +1,42 @@ +# filezilla.pp +# Install FileZilla for OS X, Ubuntu, or Windows +# https://filezilla-project.org +# + +class software::storage::filezilla ( + $ensure = $software::params::software_ensure, + $version = $software::params::filezilla_version, + $url = $software::params::filezilla_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "FileZilla-${version}": + ensure => $ensure, + provider => appcompressed, + flavor => tbz, + source => $url, + } + } + 'Ubuntu': { + package { 'filezilla': + ensure => $ensure, + } + } + 'windows': { + package { 'filezilla': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities.pp new file mode 100644 index 00000000..edde9cb0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities.pp @@ -0,0 +1,52 @@ +# utilities.pp +# +# utilities group +# Items that go in: /Applications/Utilities/ +# +# + +class software::utilities ( + $ensure = $software::params::software_ensure, + $applications_path = $software::params::applications_path, + $utilities_path = $software::params::utilities_path, + $alfred_version = $software::params::alfred_version, + $alfred_url = $software::params::alfred_url, + $controlplane_version = $software::params::controlplane_version, + $controlplane_url = $software::params::controlplane_url, + $iterm_version = $software::params::iterm_version, + $iterm_url = $software::params::iterm_url, + $onyx_url = $software::params::onyx_url, +) inherits software::params { + + class { '::software::utilities::alfred': + ensure => $ensure, + applications_path => $applications_path, + utilities_path => $utilities_path, + version => $alfred_version, + url => $alfred_url, + } + + class { '::software::utilities::controlplane': + ensure => $ensure, + applications_path => $applications_path, + utilities_path => $utilities_path, + version => $controlplane_version, + url => $controlplane_url, + } + + class { '::software::utilities::iterm': + ensure => $ensure, + applications_path => $applications_path, + utilities_path => $utilities_path, + version => $iterm_version, + url => $iterm_url, + } + + class { '::software::utilities::onyx': + ensure => $ensure, + applications_path => $applications_path, + utilities_path => $utilities_path, + url => $onyx_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/alfred.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/alfred.pp new file mode 100644 index 00000000..4630cbaa --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/alfred.pp @@ -0,0 +1,72 @@ +# alfred.pp +# Install Alfred 2 for OS X, Ubuntu, or Windows +# http://www.alfredapp.com +# +# Ubuntu gets an alternative: +# https://github.com/qdore/Mutate +# https://github.com/ManuelSchneid3r/albert +# + +class software::utilities::alfred ( + $ensure = $software::params::software_ensure, + $applications_path = $software::params::applications_path, + $utilities_path = $software::params::utilities_path, + $version = $software::params::alfred_version, + $url = $software::params::alfred_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_absolute_path($applications_path) + validate_absolute_path($utilities_path) + validate_string($version) + validate_string($url) + + $app = 'Alfred 3.app' + $app_path = "${applications_path}/${app}" + $util_path = "${utilities_path}/${app}" + + package { "Alfred-${version}": + ensure => $ensure, + provider => appcompressed, + source => $url, + } -> + + # Move to /Applications/Utilities/ + exec { "Alfred-${version}->Utilities": + command => "rm -rf '${util_path}' && mv '${app_path}' '${util_path}'", + onlyif => "test -e '${app_path}'", + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin'], + } + } + 'Ubuntu': { + $apt_ppa_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::ppa { 'ppa:mutate/ppa': + ensure => $apt_ppa_ensure, + package_manage => true, + } -> Class['apt::update'] -> + + package { 'mutate': + ensure => $ensure, + } + } + 'windows': { + package { 'wox': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/controlplane.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/controlplane.pp new file mode 100644 index 00000000..7025c7d2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/controlplane.pp @@ -0,0 +1,45 @@ +# controlplane.pp +# Install ControlPlane for OS X +# http://www.controlplaneapp.com +# + +class software::utilities::controlplane ( + $ensure = $software::params::software_ensure, + $applications_path = $software::params::applications_path, + $utilities_path = $software::params::utilities_path, + $version = $software::params::controlplane_version, + $url = $software::params::controlplane_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_absolute_path($applications_path) + validate_absolute_path($utilities_path) + validate_string($version) + validate_string($url) + + $app = 'ControlPlane.app' + $app_path = "${applications_path}/${app}" + $util_path = "${utilities_path}/${app}" + + package { "ControlPlane-${version}": + ensure => $ensure, + provider => appdmg, + source => $url, + } -> + + # Move to /Applications/Utilities/ + exec { "ControlPlane-${version}->Utilities": + command => "rm -rf '${util_path}' && mv '${app_path}' '${util_path}'", + onlyif => "test -e '${app_path}'", + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin'], + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/iterm.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/iterm.pp new file mode 100644 index 00000000..309aa24c --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/iterm.pp @@ -0,0 +1,45 @@ +# iterm.pp +# Install iTerm 2 for OS X +# http://www.iterm2.com +# + +class software::utilities::iterm ( + $ensure = $software::params::software_ensure, + $applications_path = $software::params::applications_path, + $utilities_path = $software::params::utilities_path, + $version = $software::params::iterm_version, + $url = $software::params::iterm_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_absolute_path($applications_path) + validate_absolute_path($utilities_path) + validate_string($version) + validate_string($url) + + $app = 'iTerm.app' + $app_path = "${applications_path}/${app}" + $util_path = "${utilities_path}/${app}" + + package { "iTerm-${version}": + ensure => $ensure, + provider => appcompressed, + source => $url, + } -> + + # Move to /Applications/Utilities/ + exec { "iTerm-${version}->Utilities": + command => "rm -rf '${util_path}' && mv '${app_path}' '${util_path}'", + onlyif => "test -e '${app_path}'", + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin'], + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/onyx.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/onyx.pp new file mode 100644 index 00000000..2786a789 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/onyx.pp @@ -0,0 +1,47 @@ +# onyx.pp +# Install OnyX for OS X +# http://www.titanium.free.fr +# + +class software::utilities::onyx ( + $ensure = $software::params::software_ensure, + $applications_path = $software::params::applications_path, + $utilities_path = $software::params::utilities_path, + $url = $software::params::onyx_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_absolute_path($applications_path) + validate_absolute_path($utilities_path) + # validate_string($url) + + $app = 'OnyX.app' + $app_path = "${applications_path}/${app}" + $util_path = "${utilities_path}/${app}" + + if $url { + package { "OnyX-${::macosx_productversion_major}": + ensure => $ensure, + provider => appdmg, + source => $url, + } -> + + # Move to /Applications/Utilities/ + exec { "OnyX-${::macosx_productversion_major}->Utilities": + command => "rm -rf '${util_path}' && mv '${app_path}' '${util_path}'", + onlyif => "test -e '${app_path}'", + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin'], + } + } else { + notify { "No version of OnyX for OS X ${::macosx_productversion_major} yet. It will be added when available...": } + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/openconnect.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/openconnect.pp new file mode 100644 index 00000000..e3353c2a --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/openconnect.pp @@ -0,0 +1,23 @@ +# openconnect.pp +# Install Open Client for Cisco AnyConnect VPN for Ubuntu +# Also installs the Network Management Plugin for graphical configuration +# + +class software::utilities::openconnect ( + $ensure = $software::params::software_ensure, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Ubuntu': { + package { 'network-manager-openconnect-gnome': + ensure => $ensure, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/utilities/synaptic.pp b/tools/laptop_puppetisation/modules/software/manifests/utilities/synaptic.pp new file mode 100644 index 00000000..674d403a --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/utilities/synaptic.pp @@ -0,0 +1,22 @@ +# synaptic.pp +# Install Synaptic Package Manager for Ubuntu +# + +class software::utilities::synaptic ( + $ensure = $software::params::software_ensure, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Ubuntu': { + package { 'synaptic': + ensure => $ensure, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/vcsscm.pp b/tools/laptop_puppetisation/modules/software/manifests/vcsscm.pp new file mode 100644 index 00000000..a474ce62 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/vcsscm.pp @@ -0,0 +1,22 @@ +# vcsscm.pp +# +# vcsscm group +# Version Control Systems +# Software Configuration Management +# Mainly repo editors/managers/visualizers for git and the like +# +# + +class software::vcsscm ( + $ensure = $software::params::software_ensure, + $sourcetree_version = $software::params::sourcetree_version, + $sourcetree_url = $software::params::sourcetree_url, +) inherits software::params { + + class { '::software::vcsscm::sourcetree': + ensure => $ensure, + version => $sourcetree_version, + url => $sourcetree_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/vcsscm/git.pp b/tools/laptop_puppetisation/modules/software/manifests/vcsscm/git.pp new file mode 100644 index 00000000..198e0662 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/vcsscm/git.pp @@ -0,0 +1,35 @@ +# git.pp +# Install git cli +# + +class software::vcsscm::git ( + $ensure = $software::params::software_ensure, + $gui = false, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Ubuntu': { + package { 'git': + ensure => $ensure, + } + + if $gui { + package { ['gitk', 'git-gui']: + ensure => $ensure, + } + } + } + 'windows': { + package { 'git': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/vcsscm/sourcetree.pp b/tools/laptop_puppetisation/modules/software/manifests/vcsscm/sourcetree.pp new file mode 100644 index 00000000..d943ce6c --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/vcsscm/sourcetree.pp @@ -0,0 +1,36 @@ +# sourcetree.pp +# Install SourceTree for OS X or Windows +# http://www.sourcetreeapp.com +# + +class software::vcsscm::sourcetree ( + $ensure = $software::params::software_ensure, + $version = $software::params::sourcetree_version, + $url = $software::params::sourcetree_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version) + validate_string($url) + + package { "SourceTree-${version}": + ensure => $ensure, + provider => appcompressed, + source => $url, + } + } + 'windows': { + package { 'sourcetree': + ensure => $ensure, + provider => chocolatey, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/virtualization.pp b/tools/laptop_puppetisation/modules/software/manifests/virtualization.pp new file mode 100644 index 00000000..ff6237e5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/virtualization.pp @@ -0,0 +1,22 @@ +# virtualization.pp +# +# virtualization group +# Software to manage hosted guest OSes.. +# +# + +class software::virtualization ( + $ensure = $software::params::software_ensure, + $virtualbox_version = $software::params::virtualbox_version, + $virtualbox_build = $software::params::virtualbox_build, + $virtualbox_url = $software::params::virtualbox_url, +) inherits software::params { + + class { '::software::virtualization::virtualbox': + ensure => $ensure, + version => $virtualbox_version, + build => $virtualbox_build, + url => $virtualbox_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/virtualization/vagrant.pp b/tools/laptop_puppetisation/modules/software/manifests/virtualization/vagrant.pp new file mode 100644 index 00000000..eb669930 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/virtualization/vagrant.pp @@ -0,0 +1,29 @@ +# vagrant.pp +# Install Vagrant for OS X, Ubuntu, or Windows +# https://www.vagrantup.com/ +# +# + +class software::virtualization::vagrant ( + $ensure = $software::params::software_ensure, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin', 'Ubuntu': { + include '::vagrant' + } + 'windows': { + package { 'vagrant': + ensure => $ensure, + provider => chocolatey, + install_options => ['--allow-empty-checksums'], + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/virtualization/virtualbox.pp b/tools/laptop_puppetisation/modules/software/manifests/virtualization/virtualbox.pp new file mode 100644 index 00000000..da1c9d04 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/virtualization/virtualbox.pp @@ -0,0 +1,65 @@ +# virtualbox.pp +# Install Virtual Box for OS X, Ubuntu, or Windows +# https://www.virtualbox.org +# +# + +class software::virtualization::virtualbox ( + $ensure = $software::params::software_ensure, + $version = $software::params::virtualbox_version, + $build = $software::params::virtualbox_build, + $url = $software::params::virtualbox_url, + $key = $software::params::virtualbox_key, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($version, $build, $url) + + exec { 'KillVirtualBoxProcesses': + command => 'pkill "VBoxXPCOMIPCD" || true && pkill "VBoxSVC" || true && pkill "VBoxHeadless" || true', + path => '/usr/bin:/usr/sbin:/bin:/usr/local/bin', + refreshonly => true, + } + + package { "VirtualBox-${version}-${build}": + ensure => $ensure, + provider => pkgdmg, + source => $url, + require => Exec['KillVirtualBoxProcesses'], + } + } + 'Ubuntu': { + validate_string($version, $build, $url) + $apt_source_ensure = $ensure ? { + 'installed' => present, + 'latest' => present, + default => $ensure, + } + + include '::apt' + apt::source { 'virtualbox': + ensure => $apt_source_ensure, + location => $url, + repos => 'contrib', + key => $key, + } -> Class['apt::update'] -> + + package { 'dkms': } -> + package { "virtualbox-${version}": ensure => $ensure } + } + 'windows': { + package { 'virtualbox': + ensure => $ensure, + provider => chocolatey, + install_options => ['--allow-empty-checksums'], + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/webstack.pp b/tools/laptop_puppetisation/modules/software/manifests/webstack.pp new file mode 100644 index 00000000..1ee007fe --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/webstack.pp @@ -0,0 +1,26 @@ +# webstack.pp +# +# webstack group +# Mainly: +# Servers to run web apps locally on Mac +# Zero config Rack server for rails/php apps +# +# + +class software::webstack ( + $ensure = $software::params::software_ensure, + $pow_url = $software::params::pow_url, + $anvil_url = $software::params::anvil_url, +) inherits software::params { + + # class { 'software::webstack::pow': + # ensure => $ensure, + # url => $pow_url, + # } + + class { '::software::webstack::anvil': + ensure => $ensure, + url => $anvil_url, + } + +} diff --git a/tools/laptop_puppetisation/modules/software/manifests/webstack/anvil.pp b/tools/laptop_puppetisation/modules/software/manifests/webstack/anvil.pp new file mode 100644 index 00000000..a7ddb5bb --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/manifests/webstack/anvil.pp @@ -0,0 +1,28 @@ +# anvil.pp +# Install Anvil for osx +# http://anvilformac.com +# + +class software::webstack::anvil ( + $ensure = $software::params::software_ensure, + $url = $software::params::anvil_url, +) inherits software::params { + + validate_string($ensure) + + case $::operatingsystem { + 'Darwin': { + validate_string($url) + + package { 'Anvil': + ensure => $ensure, + provider => appcompressed, + source => $url, + } + } + default: { + fail("The ${name} class is not supported on ${::operatingsystem}.") + } + } + +} diff --git a/tools/laptop_puppetisation/modules/software/metadata.json b/tools/laptop_puppetisation/modules/software/metadata.json new file mode 100644 index 00000000..67cdcfa9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/metadata.json @@ -0,0 +1,44 @@ +{ + "name": "edestecd-software", + "version": "1.1.0", + "author": "Chris Edester", + "summary": "Puppet Module to install various Desktop Software", + "license": "GPL-3.0+", + "source": "https://github.com/edestecd/puppet-software.git", + "project_page": "https://github.com/edestecd/puppet-software", + "issues_url": "https://github.com/edestecd/puppet-software/issues", + "tags": ["desktop", "software", "graphical", "gui", "browser", "chrome", "firefox", "editors", "atom", "textmate"], + "description": "The software module provides classes to install many commonly needed Desktop Applications", + "dependencies": [ + {"name": "puppetlabs/stdlib", "version_requirement": ">= 4.2.0 < 5.0.0"} + ], + "operatingsystem_support": [ + { + "operatingsystem": "Darwin", + "operatingsystemrelease": ["12.x", "13.x", "14.x", "15.x"] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": ["12.04", "14.04", "16.04"] + }, + { + "operatingsystem": "Windows", + "operatingsystemrelease": [ + "Server 2003", "Server 2003 R2", + "Server 2008", "Server 2008 R2", + "Server 2012", "Server 2012 R2", + "7", "8", "10" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": ">= 3.0.0 < 5.0.0" + }, + { + "name": "puppet", + "version_requirement": ">= 3.0.0 < 5.0.0" + } + ] +} diff --git a/tools/laptop_puppetisation/modules/software/spec/classes/software_browsers_chrome_spec.rb b/tools/laptop_puppetisation/modules/software/spec/classes/software_browsers_chrome_spec.rb new file mode 100644 index 00000000..4414879b --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/spec/classes/software_browsers_chrome_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'software::browsers::chrome' do + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts + end + + context 'with defaults' do + it { is_expected.to compile.with_all_deps } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/software/spec/classes/software_editors_atom_spec.rb b/tools/laptop_puppetisation/modules/software/spec/classes/software_editors_atom_spec.rb new file mode 100644 index 00000000..4c8af9ee --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/spec/classes/software_editors_atom_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'software::editors::atom' do + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts + end + + context 'with defaults' do + it { is_expected.to compile.with_all_deps } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/software/spec/classes/software_virtualization_virtualbox_spec.rb b/tools/laptop_puppetisation/modules/software/spec/classes/software_virtualization_virtualbox_spec.rb new file mode 100644 index 00000000..f182dd3f --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/spec/classes/software_virtualization_virtualbox_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'software::virtualization::virtualbox' do + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts + end + + context 'with defaults' do + it { is_expected.to compile.with_all_deps } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/software/spec/spec.opts b/tools/laptop_puppetisation/modules/software/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/tools/laptop_puppetisation/modules/software/spec/spec_helper.rb b/tools/laptop_puppetisation/modules/software/spec/spec_helper.rb new file mode 100644 index 00000000..2ee03bf4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/software/spec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'rubygems' if RUBY_VERSION < '1.9.0' +require 'puppetlabs_spec_helper/module_spec_helper' +require 'rspec-puppet-facts' +include RspecPuppetFacts + +RSpec.configure do |c| + c.formatter = :documentation +end diff --git a/tools/laptop_puppetisation/modules/stdlib/CHANGELOG.md b/tools/laptop_puppetisation/modules/stdlib/CHANGELOG.md new file mode 100644 index 00000000..98873f69 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/CHANGELOG.md @@ -0,0 +1,736 @@ +## 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 (master) (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 master (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/tools/laptop_puppetisation/modules/stdlib/CONTRIBUTING.md b/tools/laptop_puppetisation/modules/stdlib/CONTRIBUTING.md new file mode 100644 index 00000000..3c3f1e79 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/CONTRIBUTING.md @@ -0,0 +1,218 @@ +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 +% bundle exec 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 +% bundle exec rake spec_clean +% bundle exec 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://puppet.com/community/get-help) + +* [Writing tests](https://docs.puppet.com/guides/module_guides/bgtm.html#step-three-module-testing) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/tools/laptop_puppetisation/modules/stdlib/Gemfile b/tools/laptop_puppetisation/modules/stdlib/Gemfile new file mode 100644 index 00000000..8a568f6a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/Gemfile @@ -0,0 +1,85 @@ +#This file is generated by ModuleSync, do not edit. + +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +# Determines what type of gem is requested based on place_or_version. +def gem_type(place_or_version) + if place_or_version =~ /^git:/ + :git + elsif place_or_version =~ /^file:/ + :file + else + :gem + end +end + +# Find a location or specific version for a gem. place_or_version can be a +# version, which is most often used. It can also be git, which is specified as +# `git://somewhere.git#branch`. You can also use a file source location, which +# is specified as `file://some/location/on/disk`. +def location_for(place_or_version, fake_version = nil) + if place_or_version =~ /^(git[:@][^#]*)#(.*)/ + [fake_version, { :git => $1, :branch => $2, :require => false }].compact + elsif place_or_version =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [place_or_version, { :require => false }] + end +end + +# Used for gem conditionals +supports_windows = false + +group :development do + gem 'puppet-lint', :require => false + gem 'metadata-json-lint', :require => false, :platforms => 'ruby' + gem 'puppet_facts', :require => false + gem 'puppet-blacksmith', '>= 3.4.0', :require => false, :platforms => 'ruby' + gem 'puppetlabs_spec_helper', '>= 1.2.1', :require => false + gem 'rspec-puppet', '>= 2.3.2', :require => false + gem 'rspec-puppet-facts', :require => false, :platforms => 'ruby' + gem 'mocha', '< 1.2.0', :require => false + gem 'simplecov', :require => false, :platforms => 'ruby' + gem 'parallel_tests', '< 2.10.0', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem 'parallel_tests', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0') + gem 'rubocop', '0.41.2', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem 'rubocop', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0') + gem 'rubocop-rspec', '~> 1.6', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') + gem 'pry', :require => false + gem 'json_pure', '<= 2.0.1', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') +end + +group :system_tests do + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '~> 2.20') if supports_windows + gem 'beaker', *location_for(ENV['BEAKER_VERSION']) if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '< 3') if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker-pe', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') if ! supports_windows + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '~> 5.1') if supports_windows + gem 'beaker-puppet_install_helper', :require => false + gem 'master_manipulator', :require => false + gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) + gem 'beaker-abs', *location_for(ENV['BEAKER_ABS_VERSION'] || '~> 0.1') +end + +gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) + +# Only explicitly specify Facter/Hiera if a version has been specified. +# Otherwise it can lead to strange bundler behavior. If you are seeing weird +# gem resolution behavior, try setting `DEBUG_RESOLVER` environment variable +# to `1` and then run bundle install. +gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) if ENV['FACTER_GEM_VERSION'] +gem 'hiera', *location_for(ENV['HIERA_GEM_VERSION']) if ENV['HIERA_GEM_VERSION'] + + +# Evaluate Gemfile.local if it exists +if File.exists? "#{__FILE__}.local" + eval(File.read("#{__FILE__}.local"), binding) +end + +# Evaluate ~/.gemfile if it exists +if File.exists?(File.join(Dir.home, '.gemfile')) + eval(File.read(File.join(Dir.home, '.gemfile')), binding) +end + +# vim:ft=ruby diff --git a/tools/laptop_puppetisation/modules/stdlib/LICENSE b/tools/laptop_puppetisation/modules/stdlib/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting 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/tools/laptop_puppetisation/modules/stdlib/NOTICE b/tools/laptop_puppetisation/modules/stdlib/NOTICE new file mode 100644 index 00000000..3c8c03ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/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/tools/laptop_puppetisation/modules/stdlib/README.markdown b/tools/laptop_puppetisation/modules/stdlib/README.markdown new file mode 100644 index 00000000..a6b7bda8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/README.markdown @@ -0,0 +1,1720 @@ +# 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 + * 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 + +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. + +### Resource 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 appends the line to the end of the file to ensure the desired state. Multiple resources can 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 ensures that 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` looks for a line beginning with export followed by HTTP_PROXY and replaces 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` looks 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 contains the line being managed, the `file_line` resource autorequires that file. + +##### Parameters + +All parameters are optional, unless otherwise noted. + +* `after`: Specifies the line after which Puppet adds any new lines using a regular expression. (Existing lines are added in place.) Valid options: String containing a regex. 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 is 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. Ignored when `ensure => present`. 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 + +### Data Types + +#### `Stdlib::Absolutepath` + +A strict absolute path type. Uses a Variant of Unixpath and Windowspath types. + +Acceptable input examples: /var/log + /usr2/username/bin:/usr/local/bin:/usr/bin:. + C:\\WINDOWS\\System32 +Unacceptable input example: ../relative_path + +#### `Stdlib::Httpsurl` + +Matches https URLs. + +Acceptable input example: https://hello.com +Unacceptable input example: httds://notquiteright.org + +#### `Stdlib::Httpurl` + +Matches both https and http URLs. + +Acceptable input example: https://hello.com + http://hello.com +Unacceptable input example: httds://notquiteright.org + +#### `Stdlib::Unixpath` + +Matches paths on Unix type Operating Systems. + +Acceptable input example: /usr2/username/bin:/usr/local/bin:/usr/bin:. + /var/tmp +Unacceptable input example: C:/whatever + +#### `Stdlib::Windowspath` + +Matches paths on Windows Operating systems. + +Acceptable input example: C:\\WINDOWS\\System32 + C:\\ + \\\\host\\windows +Unacceptable input example: /usr2/username/bin:/usr/local/bin:/usr/bin:. + +### 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`, and an optional `method` ('default', 'strict', 'urlsafe') + +For backward compatibility, `method` will be set as `default` if not specified. + +*Examples:* +~~~ +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" +~~~ + +*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 are converted to respectively. If only one argument is given, it is 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 lowercases 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. + +#### `clamp` + +Keeps value within the range [Min, X, Max] by sort based on integer value (order of params doesn't matter). Takes strings, arrays or numerics. Strings are converted and compared numerically. Arrays of values are flattened into a list for further handling. For example: + * `clamp('24', [575, 187])` returns 187. + * `clamp(16, 88, 661)` returns 88. + * `clamp([4, 3, '99'])` returns 4. + *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. + +#### `deep_merge` + +Recursively merges two or more hashes together and returns the resulting hash. + $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.". +*Type*: rvalue, 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}, `delete(['ab', 'b'], 'b')` returns ['ab']. + +*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_regex` + +Deletes all instances of a given element from an array or hash that match a provided regular expression. A string will be treated as a one-item array. + +For example, `delete_regex(['a','b','c','b'], 'b')` returns ['a','c']; `delete_regex({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete_regex(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete_regex(['ab', 'b'], 'b')` returns ['ab']. + +*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. + +#### `deprecation` + +Prints deprecation warnings and logs a warning once for a given key: + +``` +deprecation(key, message) +``` + +* key: to keep the number of messages low, during the lifetime of a puppet process, only one message per key is logged. +* message: the text to be logged. + +The Puppet settings '[disable_warnings](https://docs.puppet.com/puppet/latest/reference/configuration.html#disablewarnings)', '[max_deprecations](https://docs.puppet.com/puppet/latest/reference/configuration.html#maxdeprecations)', and '[strict](https://docs.puppet.com/puppet/latest/reference/configuration.html#strict)' affect this function. Set 'strict' to `error` to fail immediately with the deprecation message, `off` to output emit no messages at all, or `warning` (default) to log all warnings. + +Additionally you can set the environment variable `STDLIB_LOG_DEPRECATIONS` to decide whether or not to log deprecation warnings: if this environment variable is set to `true`, the functions log a warning, if it is set to `false`, no warnings are logged. If no value is set at all, Puppet 4 will emit warnings, while Puppet 3 will not. Using this setting is especially useful for automated tests to avoid flooding your logs before you are ready to migrate. + +*Type*: String, String. + +#### `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. + +#### `dig` + +DEPRECATED: This function has been replaced in Puppet 4.5.0, use dig44() for backwards compatibility or use the new version. + +*Type*: rvalue. + +Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path. + +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. + +~~~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** The data structure we are working with. +2. **['a', 'b', 2]** The path array. +3. **'not_found'** The default value. It will be returned if nothing is found. + (optional, defaults to *undef*) + +#### `dig44` + +*Type*: rvalue. + +Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path. + +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. + +~~~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** The data structure we are working with. +2. **['a', 'b', 2]** The path array. +3. **'not_found'** The default value. It will be returned if nothing is found. + (optional, defaults to *undef*) + +#### `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. + +#### `enclose_ipv6` + +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. *Type*: rvalue. + +#### `ensure_packages` + +Takes a list of packages array/hash 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()` or `ensure_resources()` function. *Type*: statement. + +For Array: + + ensure_packages(['ksh','openssl'], {'ensure' => 'present'}) + +For Hash: + + ensure_packages({'ksh' => { ensure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) + +#### `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. + +#### `ensure_resources` + +Takes a resource type, title (only hash), and a hash of attributes that describe the resource(s). + +~~~ +user { 'dan': + gid => 'mygroup', + ensure => present, +} + +ensure_resources($user) +~~~ + +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' + +ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) +~~~ + +### `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 available only in Puppet 4 or in Puppet 3 with 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 [the Puppet type system](https://docs.puppetlabs.com/references/latest/type.html#about-resource-types) for more information about types. +See the [`assert_type()`](https://docs.puppetlabs.com/references/latest/function.html#asserttype) function for flexible ways to assert the type of a value. + +#### `is_absolute_path` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the given path is absolute. *Type*: rvalue. + +#### `is_array` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. + +#### `is_bool` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue. + +#### `is_domain_name` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue. + +#### `is_float` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable passed to this function is a float. *Type*: rvalue. + +#### `is_function_available` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue. + +#### `is_integer` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue. + +#### `is_ip_address` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. + +#### `is_ipv6_address` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the string passed to this function is a valid IPv6 address. *Type*: rvalue. + +#### `is_ipv4_address` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the string passed to this function is a valid IPv4 address. *Type*: rvalue. + +#### `is_mac_address` + +Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue. + +#### `is_numeric` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Returns 'true' if the variable passed to this function is a number. *Type*: rvalue. + +#### `is_string` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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 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. For example, `join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ")` results in ["a is 1","b is 2","b is 3"]. *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') + ~~~ + +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadyaml('no-file.yaml', {'default'=>'value'}) + ~~~ + +*Type*: rvalue. + +#### `loadjson` + +Loads a JSON file containing an array, string, or hash, and returns the data in the corresponding native data type. + +For example: + + ~~~ + $myhash = loadjson('/etc/puppet/data/myhash.json') + ~~~ + +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadjson('no-file.json', {'default'=>'value'}) + ~~~ + +*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 when a module's metadata file is absent: + + ~~~ + $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 is returned if the data was not correct. + +#### `parseyaml` + +Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. The optional second argument is 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` + +Returns 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"]. +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. + +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. + +#### `regexpescape` + +Regexp escape a string or array of strings. Requires either a single string or an array as an input. *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. + +#### `seeded_rand` + +Takes an integer max value and a string seed value and returns a repeatable random integer smaller than max. Like `fqdn_rand`, but does not add node specific data to the seed. *Type*: rvalue. + +#### `shell_escape` + +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, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape). + +*Example:* +~~~ +shell_escape('foo b"ar') => 'foo\ b\"ar' +~~~ + +*Type*: rvalue. + +#### `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, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shelljoin). + +*Example:* +~~~ +shell_join(['foo bar', 'ba"z']) => 'foo\ bar ba\"z' +~~~ + +*Type*: rvalue. + +#### `shell_split` + +Splits a string into an array of tokens in the same way the Bourne shell does. This function behaves the same as ruby's `Shellwords.shellsplit()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellsplit). + +*Example:* +~~~ +shell_split('foo\ bar ba\"z') => ['foo bar', 'ba"z'] +~~~ + +*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', or 'yes' to true. Strings that contain values '0', 'f', 'n', or 'no', or that are an empty string or undefined are converted to false. Any other value causes 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, or to the keys in a hash. +For example: +* `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp'] +* `suffix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'ap'=>'b','bp'=>'c','cp'=>'d'}. + +*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. + +DEPRECATED: replaced by `dig()`. + +Retrieves a value within multiple layers of hashes and arrays via a string containing a path. The path is a string of hash keys or array indexes starting with zero, separated by the path separator character (default "/"). The function goes through the structure by each path component and tries to return the value at the end of the path. + +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. 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` + +This function is provided for backwards compatibility but is generally not preferred over the built-in [type() function](https://docs.puppet.com/puppet/latest/reference/function.html#type) provided by Puppet. + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Validates that the argument is an IP address, regardless of it is an IPv4 or an IPv6 +address. It also validates IP address with netmask. The argument must be given as a string. + +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_legacy` + +Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if only one validation passes, and fails if both validations return false. + +Accepts arguments for: +* the type to check the value against, +* the full name of the previous validation function, +* the value to be checked, +* an unspecified number of arguments needed for the previous validation function. + +Example: + +``` +validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["."]) +``` + +This function supports updating modules from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking functionality for those depending on Puppet 3 style validation. + +> Note: This function is compatible only with Puppet 4.4.0 (PE 2016.1) and later. + +##### For module users + +If you are running Puppet 4, the `validate_legacy` function can help you find and resolve deprecated Puppet 3 `validate_*` functions. These functions are deprecated as of stdlib version 4.13 and will be removed in a future version of stdlib. + +Puppet 4 allows improved defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html). Data types avoid some of the problems with Puppet 3's `validate_*` functions, which could sometimes be inconsistent. For example, [validate_numeric](#validate_numeric) unintentionally allowed not only numbers, but also arrays of numbers or strings that looked like numbers. + +If you run Puppet 4 and use modules with deprecated `validate_*` functions, you might encounter deprecation messages. The `validate_legacy` function makes these differences visible and makes it easier to move to the clearer Puppet 4 syntax. + +The deprecation messages you get can vary, depending on the modules and data that you use. These deprecation messages appear by default only in Puppet 4: + +* `Notice: Accepting previously invalid value for target type ''`: This message is informational only. You're using values that are allowed by the new type, but would have been invalid by the old validation function. +* `Warning: This method is deprecated, please use the stdlib validate_legacy function`: The module has not yet upgraded to `validate_legacy`. Use the [deprecation](#deprecation) options to silence warnings for now, or submit a fix with the module's developer. See the information [for module developers](#for-module-developers) below for how to fix the issue. +* `Warning: validate_legacy() expected value, got _`: Your code passes a value that was accepted by the Puppet 3-style validation, but will not be accepted by the next version of the module. Most often, you can fix this by removing quotes from numbers or booleans. +* `Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got `: Your code passes a value that is not acceptable to either the new or the old style validation. + +##### For module developers + +The `validate_legacy` function helps you move from Puppet 3 style validation to Puppet 4 validation without breaking functionality your module's users depend on. + +Moving to Puppet 4 type validation allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html). Many of Puppet 3's `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) allows not only numbers, but also arrays of numbers or strings that look like numbers, without giving you any control over the specifics. + +For each parameter of your classes and defined types, choose a new Puppet 4 data type to use. In most cases, the new data type allows a different set of values than the original `validate_*` function. The situation then looks like this: + +| | `validate_` pass | `validate_` fail | +| ------------ | ---------------- | ---------------- | +| matches type | pass | pass, notice | +| fails type | pass, deprecated | fail | + +The code after the validation still has to handle all possible values for now, but users of your code can change their manifests to pass only values that match the new type. + +For each `validate_*` function in stdlib, there is a matching `Stdlib::Compat::*` type that allows the appropriate set of values. See the documentation in the `types/` directory in the stdlib source code for caveats. + +For example, given a class that should accept only numbers, like this: + +~~~ +class example($value) { + validate_numeric($value) +~~~ + +the resulting validation code looks like this: + +~~~ +class example( + Variant[Stdlib::Compat::Numeric, Numeric] $value +) { + validate_legacy(Numeric, 'validate_numeric', $value) +~~~ + +Here, the type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which allows any `Numeric` (the new type), as well as all values previously accepted by `validate_numeric` (through `Stdlib::Compat::Numeric`). + +The call to `validate_legacy` takes care of triggering the correct log or fail message for you. It requires the new type, the previous validation function name, and all arguments to that function. + +If your module still supported Puppet 3, this is a breaking change. Update your `metadata.json` requirements section to indicate that your module no longer supports Puppet 3, and bump the major version of your module. With this change, all existing tests for your module should still pass. Create additional tests for the new possible values. + +As a breaking change, this is also a good time to call [`deprecation`](#deprecation) for any parameters you want to get rid of, or to add additional constraints on your parameters. + +After releasing this version, you can release another breaking change release where you remove all compat types and all calls to `validate_legacy`. At that time, you can also go through your code and remove any leftovers dealing with the previously possible values. + +Always note such changes in your CHANGELOG and README. + +#### `validate_numeric` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +Validates that the first argument is a numeric value (or an array or string 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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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 terminates if the first argument is not a string. Always use quotes to force stringification: + + ~~~ + validate_re("${::operatingsystemmajrelease}", '^[57]$') + ~~~ + +*Type*: statement. + +#### `validate_slength` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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 the second argument 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` + +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** + +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. + +#### `validate_x509_rsa_key_pair` + +Validates a PEM-formatted X.509 certificate and private key using OpenSSL. +Verifies that the certficate's signature was created from the supplied key. + +Fails catalog compilation if any value fails this check. + +Takes two arguments, the first argument must be a X.509 certificate and the +second must be an RSA private key: + + ~~~ + validate_x509_rsa_key_pair($cert, $key) + ~~~ + +*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/MODULES](http://tickets.puppetlabs.com/browse/MODULES). + +## 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/tools/laptop_puppetisation/modules/stdlib/README_DEVELOPER.markdown b/tools/laptop_puppetisation/modules/stdlib/README_DEVELOPER.markdown new file mode 100644 index 00000000..04349ed7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/README_DEVELOPER.markdown @@ -0,0 +1,35 @@ +Puppet Specific Facts +===================== + +Facter is meant to stand alone and apart from Puppet. However, Facter often +runs inside Puppet and all custom facts included in the stdlib module will +almost always be evaluated in the context of Puppet and Facter working +together. + +Still, we don't want to write custom facts that blow up in the users face if +Puppet is not loaded in memory. This is often the case if the user runs +`facter` without also supplying the `--puppet` flag. + +Ah! But Jeff, the custom fact won't be in the `$LOAD_PATH` unless the user +supplies `--facter`! You might say... + +Not (always) true I say! If the user happens to have a CWD of +`/stdlib/lib` then the facts will automatically be evaluated and +blow up. + +In any event, it's pretty easy to write a fact that has no value if Puppet is +not loaded. Simply do it like this: + + Facter.add(:node_vardir) do + setcode do + # This will be nil if Puppet is not available. + Facter::Util::PuppetSettings.with_puppet do + Puppet[:vardir] + end + end + end + +The `Facter::Util::PuppetSettings.with_puppet` method accepts a block and +yields to it only if the Puppet library is loaded. If the Puppet library is +not loaded, then the method silently returns `nil` which Facter interprets as +an undefined fact value. The net effect is that the fact won't be set. diff --git a/tools/laptop_puppetisation/modules/stdlib/README_SPECS.markdown b/tools/laptop_puppetisation/modules/stdlib/README_SPECS.markdown new file mode 100644 index 00000000..917b6310 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/README_SPECS.markdown @@ -0,0 +1,7 @@ +NOTE +==== + +This project's specs depend on puppet core, and thus they require the +`puppetlabs_spec_helper` project. For more information please see the README +in that project, which can be found here: [puppetlabs spec +helper](https://github.com/puppetlabs/puppetlabs_spec_helper) diff --git a/tools/laptop_puppetisation/modules/stdlib/RELEASE_PROCESS.markdown b/tools/laptop_puppetisation/modules/stdlib/RELEASE_PROCESS.markdown new file mode 100644 index 00000000..0f9328ed --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/RELEASE_PROCESS.markdown @@ -0,0 +1,24 @@ +# Contributing to this module # + + * Work in a topic branch + * Submit a github pull request + * Address any comments / feeback + * Merge into master 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 + * 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. + * Update the CHANGELOG + * Update the Modulefile + * Commit these changes with a message along the lines of "Update CHANGELOG and + Modulefile for release" + * Create an annotated tag with git tag -a vX.Y.Z -m 'version X.Y.Z' (NOTE the + leading v as per semver.org) + * Push the tag with git push origin --tags + * Build a new package with puppet-module or the rake build task if it exists + * Publish the new package to the forge + * Bonus points for an announcement to puppet-users. diff --git a/tools/laptop_puppetisation/modules/stdlib/Rakefile b/tools/laptop_puppetisation/modules/stdlib/Rakefile new file mode 100644 index 00000000..3e8d4cb9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/Rakefile @@ -0,0 +1,38 @@ +require 'puppet_blacksmith/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppetlabs_spec_helper/rake_tasks' + +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') + +desc 'Generate pooler nodesets' +task :gen_nodeset do + require 'beaker-hostgenerator' + require 'securerandom' + require 'fileutils' + + agent_target = ENV['TEST_TARGET'] + if ! agent_target + STDERR.puts 'TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat-64default."' + agent_target = 'redhat-64default.' + end + + master_target = ENV['MASTER_TEST_TARGET'] + if ! master_target + STDERR.puts 'MASTER_TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat7-64mdcl"' + master_target = 'redhat7-64mdcl' + end + + targets = "#{master_target}-#{agent_target}" + cli = BeakerHostGenerator::CLI.new([targets]) + nodeset_dir = "tmp/nodesets" + nodeset = "#{nodeset_dir}/#{targets}-#{SecureRandom.uuid}.yaml" + FileUtils.mkdir_p(nodeset_dir) + File.open(nodeset, 'w') do |fh| + fh.print(cli.execute) + end + puts nodeset +end diff --git a/tools/laptop_puppetisation/modules/stdlib/checksums.json b/tools/laptop_puppetisation/modules/stdlib/checksums.json new file mode 100644 index 00000000..1e9f0bf6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/checksums.json @@ -0,0 +1,497 @@ +{ + "CHANGELOG.md": "38b4f291b7c2ffe1f0f8318915b63cc8", + "CONTRIBUTING.md": "b78f71c1104f00538d50ad2775f58e95", + "Gemfile": "6c471e464dc74838c2b0c3ceb407eb95", + "LICENSE": "3b83ef96387f14655fc854ddc3c6bd57", + "NOTICE": "b2e552587e5969886fdd60481e8b0351", + "README.markdown": "2a53725e800dca15cfb3648c6753109c", + "README_DEVELOPER.markdown": "220a8b28521b5c5d2ea87c4ddb511165", + "README_SPECS.markdown": "82bb4c6abbb711f40778b162ec0070c1", + "RELEASE_PROCESS.markdown": "94b92bc99ac4106ba1a74d5c04e520f9", + "Rakefile": "6db744f1deed7ae0746abe59e3d50863", + "examples/file_line.pp": "48f7f162127beffea8f8e3e58db2355a", + "examples/has_interface_with.pp": "d69d520cf3ff4d0b495480afaca359ef", + "examples/has_ip_address.pp": "32f42575e49aa66f0f2398a70ae2a9f4", + "examples/has_ip_network.pp": "bfb8db068c58d77c4dd7ae9697536537", + "examples/init.pp": "b52fd907330ddbd9c3e070cf39f7b317", + "lib/facter/facter_dot_d.rb": "d71e93183a680ac78bc0389fd50470a0", + "lib/facter/package_provider.rb": "539766a71dfb2f65e94a7c91bf413fcf", + "lib/facter/pe_version.rb": "60d47406026c8201e51394227ddf780d", + "lib/facter/puppet_settings.rb": "9e128c61600a7237cb5ed1ff25025d13", + "lib/facter/root_home.rb": "35702ae0c7410ec4d2101113e2f697fa", + "lib/facter/service_provider.rb": "66cc42526eae631e306b397391f1f01c", + "lib/facter/util/puppet_settings.rb": "9f1d2593d0ae56bfca89d4b9266aeee1", + "lib/puppet/functions/deprecation.rb": "59b803eaa15b5a559040497bffc172ae", + "lib/puppet/functions/is_a.rb": "9dad7f8c9b75348cd97aca986ac0b29a", + "lib/puppet/functions/is_absolute_path.rb": "96b217f26d06dbac87a2c6a8cfd2d8c8", + "lib/puppet/functions/is_array.rb": "9292a646010d167417a1936b0b0c17b9", + "lib/puppet/functions/is_bool.rb": "73957f9efd75ed8a7ab867f9de6da117", + "lib/puppet/functions/is_float.rb": "af3bd6bb56878bac8cc4fe4f7564e4f9", + "lib/puppet/functions/is_ip_address.rb": "ee231c66c3e039778bf46702d89815a6", + "lib/puppet/functions/is_ipv4_address.rb": "900d33249906c4daa02aa79cac896548", + "lib/puppet/functions/is_ipv6_address.rb": "568fba9af6a83c8b536fafcda82eb448", + "lib/puppet/functions/is_numeric.rb": "33051800b886cc3b2119826b77c9821a", + "lib/puppet/functions/is_string.rb": "230e9eabc5c9e1d8d5fb7b3c6c12b300", + "lib/puppet/functions/type_of.rb": "bec00841aae556993c926ab298bc81cd", + "lib/puppet/functions/validate_absolute_path.rb": "54a610baa115c7505f1b35976b632a8e", + "lib/puppet/functions/validate_array.rb": "9052b0026da174636c276a2512cf5acc", + "lib/puppet/functions/validate_bool.rb": "fe979e402a5a3a19d013ce84b39ef06a", + "lib/puppet/functions/validate_hash.rb": "92ea8fc21bbbf6cc41f6bb9cfcaefce7", + "lib/puppet/functions/validate_integer.rb": "b0982b68a599262da2c6f2e032bc7713", + "lib/puppet/functions/validate_ip_address.rb": "65a12af9a2c2a9c70d820d04d19ec891", + "lib/puppet/functions/validate_ipv4_address.rb": "4a5039b99ac97cc0447faa343b9f7416", + "lib/puppet/functions/validate_ipv6_address.rb": "fbdf685432416505fed27d5647c26f9c", + "lib/puppet/functions/validate_legacy.rb": "d9f115f30c511cef536a821b94826094", + "lib/puppet/functions/validate_numeric.rb": "41b2cc7335395f617c2bfbeac8f579da", + "lib/puppet/functions/validate_re.rb": "42092f592ebf89b8a504b10c900230d8", + "lib/puppet/functions/validate_slength.rb": "3ae6fcc3f60032c923d06ab3e457b84e", + "lib/puppet/functions/validate_string.rb": "cc967a9d0ea156b2208d1760d7f6e1b2", + "lib/puppet/parser/functions/abs.rb": "32161bd0435fdfc2aec2fc559d2b454b", + "lib/puppet/parser/functions/any2array.rb": "a81e71d6b67a551d38770ba9a1948a75", + "lib/puppet/parser/functions/any2bool.rb": "b5badfb4f9300d556b5b561d4ce599c5", + "lib/puppet/parser/functions/assert_private.rb": "1365284f9e474ecec24cfe43ee8e7cf4", + "lib/puppet/parser/functions/base64.rb": "ac8d0565df2931470447effa502c9ad3", + "lib/puppet/parser/functions/basename.rb": "c61952b3f68fd86408c84fca2c3febb1", + "lib/puppet/parser/functions/bool2num.rb": "f953f5fc094c2ae3908a72d8840ba291", + "lib/puppet/parser/functions/bool2str.rb": "6334ac6d24a8aa49a2243fb425f47311", + "lib/puppet/parser/functions/camelcase.rb": "71c67b71eac4b7f46a0dd22cb915d2e6", + "lib/puppet/parser/functions/capitalize.rb": "da131748a9d32da9eb0b6438e39377eb", + "lib/puppet/parser/functions/ceiling.rb": "dfa9b1c75ce89344026b3b5aed2d190f", + "lib/puppet/parser/functions/chomp.rb": "2b7dc42f9967edd34cfa0ba9a97229ca", + "lib/puppet/parser/functions/chop.rb": "0ec76f54afd94201f35785dfeb2092b5", + "lib/puppet/parser/functions/clamp.rb": "d19b8dfc573ed2eff7e3536ae1e5d596", + "lib/puppet/parser/functions/concat.rb": "a1b0233e58f1f8095a74fe9300c74a9b", + "lib/puppet/parser/functions/convert_base.rb": "c3b3e59a49318af98dcb88aed7156629", + "lib/puppet/parser/functions/count.rb": "9eb74eccd93e2b3c87fd5ea14e329eba", + "lib/puppet/parser/functions/deep_merge.rb": "d83696855578fb81b64b9e92b9c7cc7c", + "lib/puppet/parser/functions/defined_with_params.rb": "80eed5cedb1b5134e6a1cf44e86ae60a", + "lib/puppet/parser/functions/delete.rb": "873d8244e7ecf7b2e56a46c2b3e09b4e", + "lib/puppet/parser/functions/delete_at.rb": "6bc24b79390d463d8be95396c963381a", + "lib/puppet/parser/functions/delete_regex.rb": "2fd4485e2526510dfde0a6687e23ee6e", + "lib/puppet/parser/functions/delete_undef_values.rb": "b32d4a3925753b2eb2c318cbd7f14404", + "lib/puppet/parser/functions/delete_values.rb": "39b147f7d369bb5f809044b6341954a2", + "lib/puppet/parser/functions/deprecation.rb": "c9c5dc3f48fdb7e20d02c18d0599f697", + "lib/puppet/parser/functions/difference.rb": "e31b95fbaf974cf853a510177368bfb9", + "lib/puppet/parser/functions/dig.rb": "1a2a8918f646c13dcb9876a22f9295ab", + "lib/puppet/parser/functions/dig44.rb": "8f4255bd98fe6a558cdb43a851e58ad3", + "lib/puppet/parser/functions/dirname.rb": "8a5579f9a9a13fd737ba65eccf8e6d5a", + "lib/puppet/parser/functions/dos2unix.rb": "be8359a5106a7832be4180e8207dd586", + "lib/puppet/parser/functions/downcase.rb": "73121616d73339cf8dd10e0de61a6c50", + "lib/puppet/parser/functions/empty.rb": "b4ad0c3c00cbc56f745fbc05af1efa00", + "lib/puppet/parser/functions/enclose_ipv6.rb": "581bc163291824909d1700909db96512", + "lib/puppet/parser/functions/ensure_packages.rb": "81a8edbd7b6f85fc90e458568184c356", + "lib/puppet/parser/functions/ensure_resource.rb": "de703fe63392b939fc2b4392975263de", + "lib/puppet/parser/functions/ensure_resources.rb": "c92d8b69d6354eda24aa3a13d88177b2", + "lib/puppet/parser/functions/flatten.rb": "25777b76f9719162a8bab640e5595b7a", + "lib/puppet/parser/functions/floor.rb": "42cad4c689231a51526c55a6f0985d1f", + "lib/puppet/parser/functions/fqdn_rand_string.rb": "9ac5f18e563094aee62ef7586267025d", + "lib/puppet/parser/functions/fqdn_rotate.rb": "770d510a2e50d19b2dd42b6edef3fb1f", + "lib/puppet/parser/functions/get_module_path.rb": "d4bf50da25c0b98d26b75354fa1bcc45", + "lib/puppet/parser/functions/getparam.rb": "440a9c381b9ad589504e2e9919e83c06", + "lib/puppet/parser/functions/getvar.rb": "0c8c5cef7e158e232a8cf6e42c10d0ff", + "lib/puppet/parser/functions/grep.rb": "5682995af458b05f3b53dd794c4bf896", + "lib/puppet/parser/functions/has_interface_with.rb": "e135f09dbecc038c3aa9ae03127617ef", + "lib/puppet/parser/functions/has_ip_address.rb": "ee207f47906455a5aa49c4fb219dd325", + "lib/puppet/parser/functions/has_ip_network.rb": "b4d726c8b2a0afac81ced8a3a28aa731", + "lib/puppet/parser/functions/has_key.rb": "7cd9728c38f0b0065f832dabd62b0e7e", + "lib/puppet/parser/functions/hash.rb": "784f8d2d114eb4c9414ebd8a6868f82f", + "lib/puppet/parser/functions/intersection.rb": "c8f4f8b861c9c297c87b08bdbfb94caa", + "lib/puppet/parser/functions/is_absolute_path.rb": "1ce9a6d1cd0a79087d73cb879ed04542", + "lib/puppet/parser/functions/is_array.rb": "343cdcafdb6d353773f14e6d8864d915", + "lib/puppet/parser/functions/is_bool.rb": "92589666ef0b0cccafb2c80bb786b3ff", + "lib/puppet/parser/functions/is_domain_name.rb": "6ca1f2708add756a6803b29d593d5830", + "lib/puppet/parser/functions/is_email_address.rb": "82573a431edf5a0bf9847393af27566a", + "lib/puppet/parser/functions/is_float.rb": "363e152a18e18997be12ab61b56c3160", + "lib/puppet/parser/functions/is_function_available.rb": "628428bbcd9313ce09783d9484330e09", + "lib/puppet/parser/functions/is_hash.rb": "8c7d9a05084dab0389d1b779c8a05b1a", + "lib/puppet/parser/functions/is_integer.rb": "c5f4aeb52da82e1d87f36b4b34349767", + "lib/puppet/parser/functions/is_ip_address.rb": "87316b88db72b2359351c7ab4426cdb4", + "lib/puppet/parser/functions/is_ipv4_address.rb": "0e2862f6280bff0f4c189b9f5f37a420", + "lib/puppet/parser/functions/is_ipv6_address.rb": "066706256a142573a96afb4615fe99a6", + "lib/puppet/parser/functions/is_mac_address.rb": "6dd3c96437d49e68630869b0b464e7f2", + "lib/puppet/parser/functions/is_numeric.rb": "72d25c5f9daae0220d64636efc6977b6", + "lib/puppet/parser/functions/is_string.rb": "028bac4d729e7b9990fbd5afb8cbc21b", + "lib/puppet/parser/functions/join.rb": "a285a05c015ae278608f6454aef211ea", + "lib/puppet/parser/functions/join_keys_to_values.rb": "c17ad05bca6eb1a409d355f3f7637115", + "lib/puppet/parser/functions/keys.rb": "eb6ac815ea14fbf423580ed903ef7bad", + "lib/puppet/parser/functions/load_module_metadata.rb": "805c5476a6e7083d133e167129885924", + "lib/puppet/parser/functions/loadjson.rb": "ffecf61ba2ec8011915d37009b1a273e", + "lib/puppet/parser/functions/loadyaml.rb": "668265f14327cba1d1400f2078b7b26b", + "lib/puppet/parser/functions/lstrip.rb": "20a9b1fa077c16f34e0ef5448b895698", + "lib/puppet/parser/functions/max.rb": "f652fd0b46ef7d2fbdb42b141f8fdd1d", + "lib/puppet/parser/functions/member.rb": "2b5d7fb8f87f1c7d195933c57ca32e91", + "lib/puppet/parser/functions/merge.rb": "f3dcc5c83440cdda2036cce69b61a14b", + "lib/puppet/parser/functions/min.rb": "0d2a1b7e735ab251c5469e735fa3f4c6", + "lib/puppet/parser/functions/num2bool.rb": "605c12fa518c87ed2c66ae153e0686ce", + "lib/puppet/parser/functions/parsejson.rb": "15165fd3807d9f3d657697fa854d643d", + "lib/puppet/parser/functions/parseyaml.rb": "db54578d9d798ced75952217cf11b737", + "lib/puppet/parser/functions/pick.rb": "bf01f13bbfe2318e7f6a302ac7c4433f", + "lib/puppet/parser/functions/pick_default.rb": "ad3ea60262de408767786d37a54d45dc", + "lib/puppet/parser/functions/prefix.rb": "e377fd64bd63dde6c9660aa75aca4942", + "lib/puppet/parser/functions/private.rb": "1500a21d5cf19961c5b1d476df892d92", + "lib/puppet/parser/functions/pw_hash.rb": "d82221f667050026cd6d155432a31802", + "lib/puppet/parser/functions/range.rb": "2203172c91cc324e85433618597be3be", + "lib/puppet/parser/functions/regexpescape.rb": "f9cfb10f6acd1e318bf60bb7f561bde3", + "lib/puppet/parser/functions/reject.rb": "689f6a7c961a55fe9dcd240921f4c7f9", + "lib/puppet/parser/functions/reverse.rb": "b234b54b8cd62b2d67ccd70489ffdccf", + "lib/puppet/parser/functions/rstrip.rb": "b4e4ada41f7c1d2fcad073ce6344980f", + "lib/puppet/parser/functions/seeded_rand.rb": "2ad22e7613d894ae779c0c5b0e65dade", + "lib/puppet/parser/functions/shell_escape.rb": "b9298edaf48883d7b7d2dd8c76c25d2f", + "lib/puppet/parser/functions/shell_join.rb": "60817e59ed6eda2cc536d15c88d0d280", + "lib/puppet/parser/functions/shell_split.rb": "ed608feaf0f1c36a54a3a9459384d414", + "lib/puppet/parser/functions/shuffle.rb": "d50f72b0aeb921e64d2482f62488e2f3", + "lib/puppet/parser/functions/size.rb": "ab3b5b8cf2369d76969a7cb2564e018f", + "lib/puppet/parser/functions/sort.rb": "504b033b438461ca4f9764feeb017833", + "lib/puppet/parser/functions/squeeze.rb": "541f85b4203b55c9931d3d6ecd5c75f8", + "lib/puppet/parser/functions/str2bool.rb": "44b411fa76cd6713e37354280b102587", + "lib/puppet/parser/functions/str2saltedsha512.rb": "49afad7b386be38ce53deaefef326e85", + "lib/puppet/parser/functions/strftime.rb": "e02e01a598ca5d7d6eee0ba22440304a", + "lib/puppet/parser/functions/strip.rb": "85d70ab95492e3e4ca5f0b5ec3f284a9", + "lib/puppet/parser/functions/suffix.rb": "082519722ed6f237dd3a9a7e316ab2e4", + "lib/puppet/parser/functions/swapcase.rb": "b17a9f3cb0271451d309e4b4f52dd651", + "lib/puppet/parser/functions/time.rb": "8cb0b8320c60b4a21725634154a9f1db", + "lib/puppet/parser/functions/to_bytes.rb": "65437027687b6172173b3a211a799e37", + "lib/puppet/parser/functions/try_get_value.rb": "09cd079ec5f0e5e2ac862c9ebe0f54fe", + "lib/puppet/parser/functions/type.rb": "4709f7ab8a8aad62d77a3c5d91a3aa08", + "lib/puppet/parser/functions/type3x.rb": "f9bf4de8341afb0c677c26b40ec8a2b2", + "lib/puppet/parser/functions/union.rb": "3cf57ea53f2522f586264feb67293cd6", + "lib/puppet/parser/functions/unique.rb": "c1bb4a8aeebd09ba3e4c8bc3702cfd60", + "lib/puppet/parser/functions/unix2dos.rb": "b1f5087fcaca69d9395094204cce887a", + "lib/puppet/parser/functions/upcase.rb": "8decededec9eb33e58f961eb86f0888f", + "lib/puppet/parser/functions/uriescape.rb": "d912ba09ba3f58c70988e662e05ffbe8", + "lib/puppet/parser/functions/validate_absolute_path.rb": "c4b12e101055380386a235cd2c92ad10", + "lib/puppet/parser/functions/validate_array.rb": "bee8327014714d4cd8dbb5c46611f594", + "lib/puppet/parser/functions/validate_augeas.rb": "61e828e7759ba3e1e563e1fdd68aa80f", + "lib/puppet/parser/functions/validate_bool.rb": "971700229c4b581f67f6fadc9019eb2c", + "lib/puppet/parser/functions/validate_cmd.rb": "7df12370db442eddddcf4dd7a5364b5e", + "lib/puppet/parser/functions/validate_email_address.rb": "a72656cbfeda622cdd5cfdafdf464095", + "lib/puppet/parser/functions/validate_hash.rb": "c2ae6299148ea200f8dfcf9204875182", + "lib/puppet/parser/functions/validate_integer.rb": "65aa35f7450794aaadb6ad2c2e114df7", + "lib/puppet/parser/functions/validate_ip_address.rb": "b23c3d5ce6839e32d0186411147a6a44", + "lib/puppet/parser/functions/validate_ipv4_address.rb": "593e8f832469cb6a48c5f16ee66c3b2d", + "lib/puppet/parser/functions/validate_ipv6_address.rb": "48d3733012818993eae662839183d139", + "lib/puppet/parser/functions/validate_numeric.rb": "0e36d370262b8bdef2f88f0a3cb5b30e", + "lib/puppet/parser/functions/validate_re.rb": "d5963c404e3ac1670553f306221c2655", + "lib/puppet/parser/functions/validate_slength.rb": "6cbcfe15378ca4a780bac786223aacac", + "lib/puppet/parser/functions/validate_string.rb": "8afa7b0dcfe17bfbbb5704ad54664cc2", + "lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb": "f17427dfc42128dc1df0ab04f37942e5", + "lib/puppet/parser/functions/values.rb": "066a6e4170e5034edb9a80463dff2bb5", + "lib/puppet/parser/functions/values_at.rb": "325a899e0201e8df5bd483fec6f12d76", + "lib/puppet/parser/functions/zip.rb": "a89d5e802bc1e63e52020c2ddbaaca2c", + "lib/puppet/provider/file_line/ruby.rb": "b3d2d66ac39c43a1e7a8dd6b78952d65", + "lib/puppet/type/anchor.rb": "bbd36bb49c3b554f8602d8d3df366c0c", + "lib/puppet/type/file_line.rb": "34bfa8c554faea5e9ae1a6c519824de1", + "manifests/init.pp": "9560a09f657d7eebbfdb920cefcc1d4f", + "manifests/stages.pp": "72eb4fa624474faf23b39e57cf1590bd", + "metadata.json": "2f25037b6883546d5c203aa6e9b13f8b", + "spec/acceptance/abs_spec.rb": "538db8d037db814b455a6d741e91bb8d", + "spec/acceptance/anchor_spec.rb": "3a366ecab2fda6c20acd70eeb57c5080", + "spec/acceptance/any2array_spec.rb": "de86ead0205acbb3eca3a8a4792bdac8", + "spec/acceptance/base64_spec.rb": "1684d5dd176dd5bbd4c3c6b1e64fbcea", + "spec/acceptance/bool2num_spec.rb": "bf53ceac40d0a67551c618b11809f3f8", + "spec/acceptance/build_csv.rb": "f28ef587de764ade1513091c4906412c", + "spec/acceptance/capitalize_spec.rb": "e77ea2c37144a75a67969c0d0839adfd", + "spec/acceptance/ceiling_spec.rb": "b2718dc74a39399e342ef96fe0d00fdc", + "spec/acceptance/chomp_spec.rb": "fb0862a6b7eeb3c290e280788e705061", + "spec/acceptance/chop_spec.rb": "4e7ab2d3a441b88b667a0d8ea5b174c1", + "spec/acceptance/clamp_spec.rb": "7513fd2a6701206b4673f40728eae835", + "spec/acceptance/concat_spec.rb": "73ce39ffec7184d8ed5f0b5656ed9557", + "spec/acceptance/count_spec.rb": "d82cfcad2461b16872455d6347a8b114", + "spec/acceptance/deep_merge_spec.rb": "c335a947f1666e185e0210e661f1c78a", + "spec/acceptance/defined_with_params_spec.rb": "f27c54ade9872c63c69316f62b03c119", + "spec/acceptance/delete_at_spec.rb": "9c028b703ee0286565c9877757678f3f", + "spec/acceptance/delete_spec.rb": "31e6dfcb9cc7c16b20d47c00e6a85a1d", + "spec/acceptance/delete_undef_values_spec.rb": "6e6a66aee0c383c843b5f92ef8c8410c", + "spec/acceptance/delete_values_spec.rb": "22c9b4914d4cbc0153aa3862cb4fb50e", + "spec/acceptance/deprecation_spec.rb": "cadc56a94cbc2f13965d698f581f582d", + "spec/acceptance/difference_spec.rb": "289f4f1788feaacb304ffd54971c7e7e", + "spec/acceptance/dirname_spec.rb": "84db53878c4400a6c684c924cff05cfc", + "spec/acceptance/downcase_spec.rb": "0f094849b94a94df491ee01186473104", + "spec/acceptance/empty_spec.rb": "e5094267eb1eae007addc5e76b6d43d1", + "spec/acceptance/ensure_resource_spec.rb": "c0193d79f1db1985d313bedb93a4c7ae", + "spec/acceptance/flatten_spec.rb": "83fb08cc168a105c1d5d0df66b1d9e84", + "spec/acceptance/floor_spec.rb": "d7267b2914b1da6406224abb7489ca86", + "spec/acceptance/fqdn_rand_string_spec.rb": "45982bd0062e3ffe2dbdd5ef0359d869", + "spec/acceptance/fqdn_rotate_spec.rb": "b00226e2ae28acf4ffea8a96b6e64f01", + "spec/acceptance/get_module_path_spec.rb": "2658cdcd1abd4b7d20f53c4aced3c72a", + "spec/acceptance/getparam_spec.rb": "4d32dc5a0ee34d045242c36d77a3b482", + "spec/acceptance/getvar_spec.rb": "ba2f081a88be97c0e7004a6296294f23", + "spec/acceptance/grep_spec.rb": "98818b8b0557b80d6ff519f70ea7617c", + "spec/acceptance/has_interface_with_spec.rb": "30e27096050c43b7efdb5e6c0d54f53b", + "spec/acceptance/has_ip_address_spec.rb": "2812117ec4b88556039e8488d53c0cb0", + "spec/acceptance/has_ip_network_spec.rb": "ca75b43ff1256ead9052f2db7620db99", + "spec/acceptance/has_key_spec.rb": "6509a26a0886f7d591eaa926b2f92407", + "spec/acceptance/hash_spec.rb": "1c626457ba056bdd3936e28aa5bf503e", + "spec/acceptance/intersection_spec.rb": "40f586af7f95408a5d4a2882a4aa98f1", + "spec/acceptance/is_a_spec.rb": "03e612e76d9004ec625d9e30bb17af04", + "spec/acceptance/is_array_spec.rb": "c2ff70ce59b90b50a5aed67abaa5399d", + "spec/acceptance/is_bool_spec.rb": "c001fdecff6b0a3c9dc78774987a0b15", + "spec/acceptance/is_domain_name_spec.rb": "63e84285c26d8717fd5d4dda01e3f432", + "spec/acceptance/is_float_spec.rb": "2f0164b4d732166aa46055a2cf7b4ea9", + "spec/acceptance/is_function_available_spec.rb": "7745eba89f8719c9ca7ebf04d5b005f7", + "spec/acceptance/is_hash_spec.rb": "cff723cd8fddac45033af5dc8406d4e4", + "spec/acceptance/is_integer_spec.rb": "c09201d17d3914bba197872897fa3413", + "spec/acceptance/is_ip_address_spec.rb": "aa14cf9abf404c3fe1e761ea957871fe", + "spec/acceptance/is_ipv4_address_spec.rb": "b787114912487987801bc68d7cb15142", + "spec/acceptance/is_ipv6_address_spec.rb": "c99785448a72f9a2cfa7cd52a392b5e7", + "spec/acceptance/is_mac_address_spec.rb": "30ff4c6a63be58daa3568305617ca2a7", + "spec/acceptance/is_numeric_spec.rb": "fb9829c7a1a8d4a58836df6ff4c3386d", + "spec/acceptance/is_string_spec.rb": "44ab2578c584fad71d33239511704977", + "spec/acceptance/join_keys_to_values_spec.rb": "8aa128bbaeea65aab8d92badee3ca2b5", + "spec/acceptance/join_spec.rb": "c6378ed481265152bba9871fc5501ee6", + "spec/acceptance/keys_spec.rb": "20486e3ebee53e50dc9de3b78b9d6ae6", + "spec/acceptance/loadjson_spec.rb": "ac93a6a2379ef44b9639a20010fe1527", + "spec/acceptance/loadyaml_spec.rb": "570544f9e813ac7e28fedf8e1c37e411", + "spec/acceptance/lstrip_spec.rb": "e29ab4039b65660ec2bd76a298adcae0", + "spec/acceptance/max_spec.rb": "209cda4b83d677743afb1a8870330618", + "spec/acceptance/member_spec.rb": "d6088a4fa6321791a3067d9b9cf8914a", + "spec/acceptance/merge_spec.rb": "5f168188fa0d6b31ba5b3dac49fb609c", + "spec/acceptance/min_spec.rb": "152a7db28434a0d0378561d4f64cddcc", + "spec/acceptance/nodesets/centos-7-x64.yml": "a713f3abd3657f0ae2878829badd23cd", + "spec/acceptance/nodesets/debian-8-x64.yml": "d2d2977900989f30086ad251a14a1f39", + "spec/acceptance/nodesets/default.yml": "b42da5a1ea0c964567ba7495574b8808", + "spec/acceptance/nodesets/docker/centos-7.yml": "8a3892807bdd62306ae4774f41ba11ae", + "spec/acceptance/nodesets/docker/debian-8.yml": "ac8e871d1068c96de5e85a89daaec6df", + "spec/acceptance/nodesets/docker/ubuntu-14.04.yml": "dc42ee922a96908d85b8f0f08203ce58", + "spec/acceptance/num2bool_spec.rb": "e4a00b913b08c68a689837e9f9336cb2", + "spec/acceptance/parsejson_spec.rb": "5753b9dd66e4fd464c132b39487b922c", + "spec/acceptance/parseyaml_spec.rb": "991f6f7b729812535155643c11846bcb", + "spec/acceptance/pick_default_spec.rb": "1bc2562380ef6f6cded5ec90a03922be", + "spec/acceptance/pick_spec.rb": "272c54c8f9398f499768331bdb4276ee", + "spec/acceptance/prefix_spec.rb": "da620568c6771e7d492ec1ff697c531c", + "spec/acceptance/pw_hash_spec.rb": "721fe0da04d798a353799fd651bcd0fc", + "spec/acceptance/range_spec.rb": "65e5b98ceca257658604d988fbec7d03", + "spec/acceptance/reject_spec.rb": "b5185f1a6071c9bdc7aca92e6f899c3e", + "spec/acceptance/reverse_spec.rb": "7bdee543e82532e97bbf7a067140031c", + "spec/acceptance/rstrip_spec.rb": "28a64ceb7cb5ae8a93d31f49816190ab", + "spec/acceptance/shuffle_spec.rb": "8a8652e57d56f2b4946cdf4d20052b7a", + "spec/acceptance/size_spec.rb": "ae17d8a55921a0570972200c7c9327e1", + "spec/acceptance/sort_spec.rb": "d44b1b8c090f0f00a2f38515fda431ea", + "spec/acceptance/squeeze_spec.rb": "adcd65fa4e72203b97f1f14c8835c2cd", + "spec/acceptance/str2bool_spec.rb": "55ad165ceef6b9ba32bf20ca3b53b44c", + "spec/acceptance/str2saltedsha512_spec.rb": "b684c4214d06ae3d5bae055262a5ccaa", + "spec/acceptance/strftime_spec.rb": "0f4eadbd74445b35de4a42c9790fbcc1", + "spec/acceptance/strip_spec.rb": "6767da5bc735beb5362aeee6ff692c9e", + "spec/acceptance/suffix_spec.rb": "07dfc7eed48b75fcc1b93d0308243eda", + "spec/acceptance/swapcase_spec.rb": "5c3c1bc19a09fed6e01881f79b0b4ea5", + "spec/acceptance/time_spec.rb": "044b2f634a1fa6ecc735998d68a93b73", + "spec/acceptance/to_bytes_spec.rb": "f9df1f234b9409f5eaf56ef24e651c36", + "spec/acceptance/try_get_value_spec.rb": "db7c47f372f9d9725987ebe13e6039eb", + "spec/acceptance/type_spec.rb": "4297e038a8ff7e6ecb859b8b68c7b3a6", + "spec/acceptance/union_spec.rb": "f24e166bc838c9c8cbd75ad3f8f9d15b", + "spec/acceptance/unique_spec.rb": "9b00b21cefde3b5391f50eeb9cd2493b", + "spec/acceptance/unsupported_spec.rb": "09b9265ecb05252cd5e5a18327c7ae97", + "spec/acceptance/upcase_spec.rb": "ffd1d6f9e6ec24131fb78983c53a75f9", + "spec/acceptance/uriescape_spec.rb": "13daa387714cbfc63b587aaa8dbf7fcd", + "spec/acceptance/validate_absolute_path_spec.rb": "8b9ebfae80329231d84fcab606a3eeaf", + "spec/acceptance/validate_array_spec.rb": "31f322a0dd69c6b99b0ca896aa4234c3", + "spec/acceptance/validate_augeas_spec.rb": "c26b8ca2184a9dd87033a0c6f0553093", + "spec/acceptance/validate_bool_spec.rb": "93d0258e9970275540859f60f1fce145", + "spec/acceptance/validate_cmd_spec.rb": "e9260c49d880e4de54f77bf4fd70cff4", + "spec/acceptance/validate_hash_spec.rb": "3e9b403da499187428922411fb7524e4", + "spec/acceptance/validate_ipv4_address_spec.rb": "dc901bbd05c3764a93cb49154cea6e4b", + "spec/acceptance/validate_ipv6_address_spec.rb": "c0872c56230ac2800cd5723eaa5bc53a", + "spec/acceptance/validate_re_spec.rb": "b289909078d6ae0d015419f518566698", + "spec/acceptance/validate_slength_spec.rb": "f0a05c1c2b895b096cb7326df4821594", + "spec/acceptance/validate_string_spec.rb": "0206e4a553f1cafd86579e370fc2d767", + "spec/acceptance/values_at_spec.rb": "669b26c4d47742051472003518c3aa61", + "spec/acceptance/values_spec.rb": "9681223bb1bd755c28946ef0bcd6ece9", + "spec/acceptance/zip_spec.rb": "86d1b555745ee873da68c71f1e46ed21", + "spec/aliases/absolute_path_spec.rb": "b5900a689c3e208fa4a1c952ae6fe9a3", + "spec/aliases/absolutepath_spec.rb": "65edf0610bad8ceb83b4cf10e7080692", + "spec/aliases/array_spec.rb": "afc957900cb7fcdfd97000c94efad22f", + "spec/aliases/bool_spec.rb": "3fd6b08c7ef1edd00b7e494b84298e2b", + "spec/aliases/float_spec.rb": "7abb4672d6c4bd2158e738daf5ae5b54", + "spec/aliases/httpsurl_spec.rb": "57cbff144a0ecd61ce1ce2f5a33b42f5", + "spec/aliases/httpurl_spec.rb": "d5a11112c8db6da609061ef37e758ba8", + "spec/aliases/integer_spec.rb": "5dd01ec9cbcc2fe9e5a89aab49b473c7", + "spec/aliases/ip_address.rb": "57d5b1fdd5e4d626512cc164ddb455a6", + "spec/aliases/ipv4_spec.rb": "734711450cbc20ff4991bf48d110fbbb", + "spec/aliases/ipv6_spec.rb": "9300d1b25cc8730023ca09ab8e5aafc8", + "spec/aliases/numeric_spec.rb": "39d0d7581f71b40d94fc12a49ef895ea", + "spec/aliases/string_spec.rb": "1e3062f3030de5896efce54ec648ee8f", + "spec/aliases/unixpath_spec.rb": "4ebd927dc0f4b464a7e985fb68260794", + "spec/aliases/windowspath_spec.rb": "0423b4daf8b18170b7687345f2b010c8", + "spec/fixtures/dscacheutil/root": "e1a7622f55f3d1be258c9a5b16b474be", + "spec/fixtures/lsuser/root": "2ed657fa157372a81634539bb1a56be8", + "spec/fixtures/test/manifests/absolute_path.pp": "79e9da69f05adc0e1ed41c20bf14e95f", + "spec/fixtures/test/manifests/absolutepath.pp": "8561fa141028cd38d0b8409cd69a1372", + "spec/fixtures/test/manifests/array.pp": "0e1d4146a9b2dd56063b2cab6f3d7571", + "spec/fixtures/test/manifests/bool.pp": "cf75826f36025bd73ff7f479acf7196d", + "spec/fixtures/test/manifests/float.pp": "132f9a63e60bba2fba68be83208c2e28", + "spec/fixtures/test/manifests/httpsurl.pp": "9047fc382d215ae55c065b0798a82a2d", + "spec/fixtures/test/manifests/httpurl.pp": "7165bf5607a4808f3da3f9baca911240", + "spec/fixtures/test/manifests/integer.pp": "3cb3807714ddcde25cd8eeca61581e3b", + "spec/fixtures/test/manifests/ip_address.pp": "78deea27fe1ff9e85c360eced4d2c256", + "spec/fixtures/test/manifests/ipv4.pp": "b4f0dfe6ae06d4f8b284d24e55f6a6a2", + "spec/fixtures/test/manifests/ipv6.pp": "4764f683b6013556e20d8669b21b5bdc", + "spec/fixtures/test/manifests/numeric.pp": "bffd26d7c0bb53628369f42c14b342cb", + "spec/fixtures/test/manifests/string.pp": "27b69c1eb36250bfbd474a0ef9ba847b", + "spec/fixtures/test/manifests/unixpath.pp": "fd062024efdf731e19026901d3fcc075", + "spec/fixtures/test/manifests/windowspath.pp": "7f942ec8f883a3ac0fcaf960ea24b7d8", + "spec/functions/abs_spec.rb": "7c0ebbd787b788d32b9bb21fe9061a2f", + "spec/functions/any2array_spec.rb": "c5990164adbaaf4f6536df4022309176", + "spec/functions/any2bool_spec.rb": "d090dde9be26601a38980e8f77fa5970", + "spec/functions/assert_private_spec.rb": "a7e79ac7a1b28610a0e57e38e913c9fa", + "spec/functions/base64_spec.rb": "fa279d9a4f3060ee3f467e35b050d528", + "spec/functions/basename_spec.rb": "84a6567266725376d7ab518ab7dc5fe8", + "spec/functions/bool2num_spec.rb": "6609136ff067b90d41cf27bf8838c3ea", + "spec/functions/bool2str_spec.rb": "52560617234393f960aedb496b49a628", + "spec/functions/camelcase_spec.rb": "4a13d3323535291fef3f40a96710acdb", + "spec/functions/capitalize_spec.rb": "31a8d497b274653d5ede70a0187d4053", + "spec/functions/ceiling_spec.rb": "47bd74569f8979d9195df06a863de93b", + "spec/functions/chomp_spec.rb": "6749a0b358b34e73843e1a284cead44a", + "spec/functions/chop_spec.rb": "6e33e61f50459191387c87e474d3d127", + "spec/functions/clamp_spec.rb": "65dab1e9aceb2cb4e41ef9c0c65a7ba3", + "spec/functions/concat_spec.rb": "d217a63169e819e1ae2445083c248aa6", + "spec/functions/convert_base_spec.rb": "f031e84b18cb010bc6233be3e4bcff83", + "spec/functions/count_spec.rb": "d91a084665ecd902586d26c99d45beed", + "spec/functions/deep_merge_spec.rb": "d70a71c7e9363c75224fffd40fc5efdd", + "spec/functions/defined_with_params_spec.rb": "4d8d3768456bfbf620a07a555c402518", + "spec/functions/delete_at_spec.rb": "a5443ac5879992af9c4470e59f0355cf", + "spec/functions/delete_regex_spec.rb": "c049a3926aded4b6a804f1c824c57d2f", + "spec/functions/delete_spec.rb": "c257307c4e4be222a82c9e0d82ced241", + "spec/functions/delete_undef_values_spec.rb": "6bee6b89a507130a009a9e8b5ef3e130", + "spec/functions/delete_values_spec.rb": "0d2d17c0cacd7f3871ea7ab2f5b96d93", + "spec/functions/deprecation_spec.rb": "6a985ff7f51090ddcd214f26dca9a727", + "spec/functions/difference_spec.rb": "2caaab5edb42ddc426e65348b12ebcc3", + "spec/functions/dig44_spec.rb": "420e2f5ee9eaeccb14c6826c4cd4d903", + "spec/functions/dig_spec.rb": "61708160da38852c3c78bc8563e0fcb2", + "spec/functions/dirname_spec.rb": "5c905655d551b1956b6c9eda4ee96569", + "spec/functions/dos2unix_spec.rb": "95c13597be9e67e79e69ed0e6c3d325a", + "spec/functions/downcase_spec.rb": "e2c24d41c6fb840f7b66c5205c942780", + "spec/functions/empty_spec.rb": "e6d06c193869ce8c97d3e67d5c5c5b4f", + "spec/functions/ensure_packages_spec.rb": "76e89bf81ae98e52d2a07263c0e8d4f4", + "spec/functions/ensure_resource_spec.rb": "eae823fcfb387ab3601794badad4bd62", + "spec/functions/flatten_spec.rb": "6fb563c36daf40599a414c1f3af8dc0b", + "spec/functions/floor_spec.rb": "7d110b1f994432e1c6c7c004a3dedbe4", + "spec/functions/fqdn_rand_string_spec.rb": "2edaae1764df4d751684d8ceda7b9cda", + "spec/functions/fqdn_rotate_spec.rb": "e9b1ce122788f18611cf64696d666328", + "spec/functions/get_module_path_spec.rb": "ef22bd80ce5dedb069830d5aa10572c1", + "spec/functions/getparam_spec.rb": "8fd26dbe9cf3f0f989968db151fba2be", + "spec/functions/getvar_spec.rb": "f2b6de68826fdb70c97c35ac8f615f48", + "spec/functions/grep_spec.rb": "b9d0722e7708351b0114c46d4272f760", + "spec/functions/has_interface_with_spec.rb": "473c000e461c3497f8461eb17cf73430", + "spec/functions/has_ip_address_spec.rb": "7b36b993ea32757e74be9909906bd165", + "spec/functions/has_ip_network_spec.rb": "23021acd604dc4ca3a1fef62e8863d8e", + "spec/functions/has_key_spec.rb": "6bc81bc7d179d4b680e7065a60b76562", + "spec/functions/hash_spec.rb": "4519b75eeb8eb0bba80b4594c297cf5e", + "spec/functions/intersection_spec.rb": "fcd475963335b3efee99c3ddd0ddd969", + "spec/functions/is_a_spec.rb": "51b1f473786fbd1d723febf20281de23", + "spec/functions/is_array_spec.rb": "26d7eab025f333d2c4a8baf89ef4e36e", + "spec/functions/is_bool_spec.rb": "40569a4cdb50af0cc21ad749ac18e6ef", + "spec/functions/is_domain_name_spec.rb": "4ea3825d5b77a5d75eab8228dcc738f9", + "spec/functions/is_email_address_spec.rb": "699c4573dfd00db8993a18afc0eaf875", + "spec/functions/is_float_spec.rb": "8aedd9e622cd1b861d99523532dc4fc1", + "spec/functions/is_function_available.rb": "f8ab234d536532c3629ff6a5068e7877", + "spec/functions/is_hash_spec.rb": "11563529f0f1f821769edb3131277100", + "spec/functions/is_integer_spec.rb": "21a139f9a87b1561bfec60de26c435a2", + "spec/functions/is_ip_address_spec.rb": "04a15328803bb47ae431eff63aa555df", + "spec/functions/is_ipv4_address_spec.rb": "339b8c79925bb70c0de19468d58ab64a", + "spec/functions/is_ipv6_address_spec.rb": "9743a0f2bfda70ace128d2f476a208b9", + "spec/functions/is_mac_address_spec.rb": "748b7e3dffae6d4097da9cc29a37e94d", + "spec/functions/is_numeric_spec.rb": "cb846f44e8f6d79161686d7b3729967c", + "spec/functions/is_string_spec.rb": "56f34694781dfcf774e43bca06057fec", + "spec/functions/join_keys_to_values_spec.rb": "d94b3c7de6565b8887098aa00148c8a5", + "spec/functions/join_spec.rb": "2181956bf08efe90f932a17e5138a25c", + "spec/functions/keys_spec.rb": "8a6772daf2ae821e98d392f5266fdf67", + "spec/functions/load_module_metadata_spec.rb": "47058522f85cd337b9a8bf64332e6fd3", + "spec/functions/loadjson_spec.rb": "51d89fdd4a21df91e7610e081096159d", + "spec/functions/loadyaml_spec.rb": "b5c574a562ed5e0ac0f2dcbbcadb5922", + "spec/functions/lstrip_spec.rb": "58644ca945b38ec8b3d8729423aacf69", + "spec/functions/max_spec.rb": "47de8d59070d8d51b2184731f5d1aa43", + "spec/functions/member_spec.rb": "02891f40caaca15a5aba43443c7d2ccb", + "spec/functions/merge_spec.rb": "56297527d192640bbe82c7ccf1e39815", + "spec/functions/min_spec.rb": "8b38e2a989912406cd2c57dcd3a460c4", + "spec/functions/num2bool_spec.rb": "7c4fd30e41a11b1bd0d9e5233340f16b", + "spec/functions/parsejson_spec.rb": "656300186e986725982595c262f7eccd", + "spec/functions/parseyaml_spec.rb": "67b3be346368a2070535585a51bcd7c2", + "spec/functions/pick_default_spec.rb": "bef7bb2f755e665775aa0085c6897fb2", + "spec/functions/pick_spec.rb": "8fe02695ea909e993119254accc61f1a", + "spec/functions/prefix_spec.rb": "95956321291a0f6d1e2f45572569fe3b", + "spec/functions/private_spec.rb": "f404771c4590a0cd7ce61ddff8f3eb7b", + "spec/functions/pw_hash_spec.rb": "640609cc73b4c8bbcdfc88c3e9797664", + "spec/functions/range_spec.rb": "e73c3bb7f2c25540780c3bad19b30994", + "spec/functions/regexpescape_spec.rb": "74b08b1f49db39228eae1e9dffcb00c9", + "spec/functions/reject_spec.rb": "e0eb0546885dd0aef023dfa4694155db", + "spec/functions/reverse_spec.rb": "cb48f198c2a9efe224a00d67e68d978f", + "spec/functions/rstrip_spec.rb": "f0391a775d335e2a5c9335d50c657f4b", + "spec/functions/seeded_rand_spec.rb": "d7d80c3458706e83a8087e17c8a7b6ab", + "spec/functions/shell_escape_spec.rb": "516354927a87ea49dbdae154be7e925a", + "spec/functions/shell_join_spec.rb": "f58c5a7bfec68a2d6602dc79453ac586", + "spec/functions/shell_split_spec.rb": "7a29c6a49236e3c7da73ea28dd94be00", + "spec/functions/shuffle_spec.rb": "6ab6083720cfd4dfa99556e5ef81f576", + "spec/functions/size_spec.rb": "51495c464a203d9e1919008209f05cd5", + "spec/functions/sort_spec.rb": "d9533dd37c6263b92895f7eba8485248", + "spec/functions/squeeze_spec.rb": "549af334b7f9dd5f06d6b45c3e3e8303", + "spec/functions/str2bool_spec.rb": "607b25fb0badd0da5acb86c63437c8be", + "spec/functions/str2saltedsha512_spec.rb": "07586b0026757cd39229c12c7221808b", + "spec/functions/strftime_spec.rb": "f1a34fc930940213abfba3095d5d8065", + "spec/functions/strip_spec.rb": "0cb8537f2e7df14f42247349ab3161a6", + "spec/functions/suffix_spec.rb": "65172f6879c902802230f718ea9df7da", + "spec/functions/swapcase_spec.rb": "90bace1b004aa63d46eb6481c6dce2b1", + "spec/functions/time_spec.rb": "6dc8f5b42cf89345d2de424bfe19be90", + "spec/functions/to_bytes_spec.rb": "b771f8490d922de46a519e407d358139", + "spec/functions/try_get_value_spec.rb": "b917b899f5d29764dd4b1b07e07ec6ce", + "spec/functions/type3x_spec.rb": "eed4ce3a2bc92d14effedefef9690654", + "spec/functions/type_of_spec.rb": "83755d9390b9c00e086a007edff7fd9b", + "spec/functions/type_spec.rb": "7a61b4af7d3d83be590d783a7e5e80f8", + "spec/functions/union_spec.rb": "089b03e9a6ef25cdcf68157bb986d8a8", + "spec/functions/unique_spec.rb": "b793c531b4d227ae55d05a187b706fb8", + "spec/functions/unix2dos_spec.rb": "628c8a0c608d1fa0dd09bd1b5af97c1f", + "spec/functions/upcase_spec.rb": "4f0461a20c03d618f0c18da39bebcf65", + "spec/functions/uriescape_spec.rb": "1458afbe7e7e11dcaad8d295a7f2be59", + "spec/functions/validate_absolute_path_spec.rb": "5adbf0a0ac8b23e86195deaf3e4bd371", + "spec/functions/validate_array_spec.rb": "3aa76f3731754c637acc94b59c79efb0", + "spec/functions/validate_augeas_spec.rb": "d598e89a23912be9f24d39b809f30b47", + "spec/functions/validate_bool_spec.rb": "d1b43cd294d0588ac6d67d5d3c77a42a", + "spec/functions/validate_cmd_spec.rb": "05eb581532fc689ff91212413b2e678d", + "spec/functions/validate_email_address_spec.rb": "1296f9934d102258091379ee07f9a2a8", + "spec/functions/validate_hash_spec.rb": "0b3ac3f7262f13ef14e3df937c8d104c", + "spec/functions/validate_integer_spec.rb": "ec55ab34e3ec4f09722349cd6aac77a6", + "spec/functions/validate_ip_address_spec.rb": "ba8c92e30f1af9e6839a2901e002c3f3", + "spec/functions/validate_ipv4_address_spec.rb": "d5d956651629f95ea531ac03b71e247b", + "spec/functions/validate_ipv6_address_spec.rb": "6ea36d17568e1d25b2d45a0b51e6f6b1", + "spec/functions/validate_legacy_spec.rb": "d51c5b1d377e7b7b66737a6f7f64fb52", + "spec/functions/validate_numeric_spec.rb": "c2f01b9c9aeae75683563ef7d3951bbb", + "spec/functions/validate_re_spec.rb": "27bcf99cd815b755548cd3979753b2f3", + "spec/functions/validate_slength_spec.rb": "c292023b2e61298499ff1f791fc03005", + "spec/functions/validate_string_spec.rb": "bc6735359ada0b3ccf69f515231e3808", + "spec/functions/validate_x509_rsa_key_pair_spec.rb": "24810bdb8ac473ae1168f1b2c5708170", + "spec/functions/values_at_spec.rb": "c318f66de43f8e6095d28f733f55ec5d", + "spec/functions/values_spec.rb": "5550da71a69514f8be87a12b575d5228", + "spec/functions/zip_spec.rb": "4c991f26985096b3e8b336cef528aa00", + "spec/monkey_patches/alias_should_to_must.rb": "b19ee31563afb91a72f9869f9d7362ff", + "spec/monkey_patches/publicize_methods.rb": "c690e444b77c871375d321e413e28ca1", + "spec/spec_helper.rb": "b2db3bc02b4ac2fd5142a6621c641b07", + "spec/spec_helper_acceptance.rb": "4ff813a78893b35f04b92b0db0908212", + "spec/spec_helper_local.rb": "1e3ad3c06a11cbcb813dc1d31973cbda", + "spec/support/shared_data.rb": "9758f8ba2958965d287387a2513dac73", + "spec/unit/facter/facter_dot_d_spec.rb": "420339a544851f2c7ee6fa4c651bdce8", + "spec/unit/facter/package_provider_spec.rb": "3a6ba799822fbcabc9adab5880260b7a", + "spec/unit/facter/pe_version_spec.rb": "d0fa6c0d5b01a4b9fd36ed4168635e9f", + "spec/unit/facter/root_home_spec.rb": "036c160d5543f4f3e80a300a3a170b77", + "spec/unit/facter/service_provider_spec.rb": "a97efb411817a44c511cd6cd79d9af8c", + "spec/unit/facter/util/puppet_settings_spec.rb": "6f9df9b10a1b39245ecdf002616a4122", + "spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb": "0145a78254ea716e5e7600d9464318a8", + "spec/unit/puppet/parser/functions/is_absolute_path_spec.rb": "52f8d3b9011fb1fd8a2a429fe8b2ae08", + "spec/unit/puppet/provider/file_line/ruby_spec.rb": "d269e18953fc297786a8393b20842abc", + "spec/unit/puppet/type/anchor_spec.rb": "06a669dffa44d716bf19b4e7f5f1d75d", + "spec/unit/puppet/type/file_line_spec.rb": "af824724caf0071d84464042490a6f88", + "types/absolutepath.pp": "3ae6f48dd95835df87c5dacea13c88d2", + "types/compat/absolute_path.pp": "6d0e102d1098d85d97c8f13051cb2c10", + "types/compat/array.pp": "43c41022dd743d55c8e9e82ce3ed741c", + "types/compat/bool.pp": "6e0cd7b2a7e1b9efaa0e273937211e58", + "types/compat/float.pp": "fd134a0e0e1abd420cec2107780a7afa", + "types/compat/integer.pp": "e85a20e42b3afaf5ec0718a8d9f9c5e3", + "types/compat/ip_address.pp": "d42c7435de30a469a71b69c45d642da7", + "types/compat/ipv4.pp": "c84eb3764f45b256a09be68afe61b749", + "types/compat/ipv6.pp": "7a0da0f553e43e03901b0c94c4ba934b", + "types/compat/numeric.pp": "f864539d78e95dabf0bab361b4ccc042", + "types/compat/re.pp": "70b05d4697e61f9af0c212ba063f395d", + "types/compat/string.pp": "b9a179664c85e121aa0277021627d126", + "types/httpsurl.pp": "108225d0273e17d541b239882287ed15", + "types/httpurl.pp": "4ba64825b11af75997c59b5acf07c62d", + "types/unixpath.pp": "20b1f9301026a2ec3bc6166a2b3613d8", + "types/windowspath.pp": "4c1eda331ecb43de98c29ed22d0ad448" +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/stdlib/examples/file_line.pp b/tools/laptop_puppetisation/modules/stdlib/examples/file_line.pp new file mode 100644 index 00000000..85b13258 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/examples/file_line.pp @@ -0,0 +1,9 @@ +# This is a simple smoke test +# of the file_line resource type. +file { '/tmp/dansfile': + ensure => file, +} -> +file_line { 'dans_line': + line => 'dan is awesome', + path => '/tmp/dansfile', +} diff --git a/tools/laptop_puppetisation/modules/stdlib/examples/has_interface_with.pp b/tools/laptop_puppetisation/modules/stdlib/examples/has_interface_with.pp new file mode 100644 index 00000000..a578dd27 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/examples/has_interface_with.pp @@ -0,0 +1,9 @@ +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')) +info('has_interface_with(\'ipaddress\', \'127.0.0.100\'):', has_interface_with('ipaddress', '127.0.0.100')) +info('has_interface_with(\'network\', \'127.0.0.0\'):', has_interface_with('network', '127.0.0.0')) +info('has_interface_with(\'network\', \'128.0.0.0\'):', has_interface_with('network', '128.0.0.0')) +info('has_interface_with(\'netmask\', \'255.0.0.0\'):', has_interface_with('netmask', '255.0.0.0')) +info('has_interface_with(\'netmask\', \'256.0.0.0\'):', has_interface_with('netmask', '256.0.0.0')) diff --git a/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_address.pp b/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_address.pp new file mode 100644 index 00000000..594143d6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_address.pp @@ -0,0 +1,3 @@ +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/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_network.pp b/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_network.pp new file mode 100644 index 00000000..1f1130dc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/examples/has_ip_network.pp @@ -0,0 +1,3 @@ +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/tools/laptop_puppetisation/modules/stdlib/examples/init.pp b/tools/laptop_puppetisation/modules/stdlib/examples/init.pp new file mode 100644 index 00000000..ad279721 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/examples/init.pp @@ -0,0 +1 @@ +include ::stdlib diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/facter_dot_d.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/facter_dot_d.rb new file mode 100644 index 00000000..5c5fb1fd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/facter_dot_d.rb @@ -0,0 +1,202 @@ +# 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 StandardError => 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 StandardError => 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 StandardError => 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 StandardError => 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/tools/laptop_puppetisation/modules/stdlib/lib/facter/package_provider.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/package_provider.rb new file mode 100644 index 00000000..3a9117fd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/package_provider.rb @@ -0,0 +1,21 @@ +# Fact: package_provider +# +# Purpose: Returns the default provider Puppet will choose to manage packages +# on this system +# +# Resolution: Instantiates a dummy package resource and return the provider +# +# Caveats: +# +require 'puppet/type' +require 'puppet/type/package' + +Facter.add(:package_provider) do + setcode do + if defined? Gem and Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/pe_version.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/pe_version.rb new file mode 100644 index 00000000..c9f2181c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/pe_version.rb @@ -0,0 +1,58 @@ +# 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 +# +# Resolution: Uses a regex match against puppetversion to determine whether the +# machine has Puppet Enterprise installed, and what version (overall, major, +# minor, patch) is installed. +# +# Caveats: +# +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 + end + end +end + +Facter.add("is_pe") do + setcode do + if Facter.value(:pe_version).to_s.empty? then + false + else + true + end + end +end + +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 + end +end + +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 + end +end + +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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/puppet_settings.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/puppet_settings.rb new file mode 100644 index 00000000..e6a066ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/puppet_settings.rb @@ -0,0 +1,35 @@ +# 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 master 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.exists?(rb_file) or raise e +end + + +# These will be nil if Puppet is not available. +Facter.add(:puppet_vardir) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:vardir] + end + end +end + +Facter.add(:puppet_environmentpath) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:environmentpath] + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/root_home.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/root_home.rb new file mode 100644 index 00000000..87c76571 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/root_home.rb @@ -0,0 +1,45 @@ +# 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 + +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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/service_provider.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/service_provider.rb new file mode 100644 index 00000000..a1179211 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/service_provider.rb @@ -0,0 +1,17 @@ +# Fact: service_provider +# +# Purpose: Returns the default provider Puppet will choose to manage services +# on this system +# +# Resolution: Instantiates a dummy service resource and return the provider +# +# Caveats: +# +require 'puppet/type' +require 'puppet/type/service' + +Facter.add(:service_provider) do + setcode do + Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/facter/util/puppet_settings.rb b/tools/laptop_puppetisation/modules/stdlib/lib/facter/util/puppet_settings.rb new file mode 100644 index 00000000..1ad94521 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/facter/util/puppet_settings.rb @@ -0,0 +1,21 @@ +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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/deprecation.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/deprecation.rb new file mode 100644 index 00000000..39d9bc7f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/deprecation.rb @@ -0,0 +1,29 @@ +# Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It 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) *Type*: String, String. +# + +Puppet::Functions.create_function(:deprecation) do + dispatch :deprecation do + param 'String', :key + param 'String', :message + end + + def deprecation(key, message) + if defined? Puppet::Pops::PuppetStack.stacktrace() + stacktrace = Puppet::Pops::PuppetStack.stacktrace() + file = stacktrace[0] + line = stacktrace[1] + message = "#{message} at #{file}:#{line}" + end + # depending on configuration setting of strict + case Puppet.settings[:strict] + when :off + # do nothing + when :error + fail("deprecation. #{key}. #{message}") + else + unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false' + Puppet.deprecation_warning(message, key) + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_a.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_a.rb new file mode 100644 index 00000000..da98b035 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_a.rb @@ -0,0 +1,32 @@ +# 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 +# # 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!': } +# } +# +# 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 + dispatch :is_a do + param 'Any', :value + param 'Type', :type + end + + def is_a(value, type) + # See puppet's lib/puppet/pops/evaluator/evaluator_impl.rb eval_MatchExpression + Puppet::Pops::Types::TypeCalculator.instance?(type, value) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_absolute_path.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_absolute_path.rb new file mode 100644 index 00000000..b61064a7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_absolute_path.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_absolute_path) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_absolute_path', "This method is deprecated, please use match expressions with Stdlib::Compat::Absolute_Path instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_absolute_path", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_array.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_array.rb new file mode 100644 index 00000000..a29fe8a2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_array.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_array) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_array', "This method is deprecated, please use match expressions with Stdlib::Compat::Array instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_array", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_bool.rb new file mode 100644 index 00000000..6e2c22ba --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_bool.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_bool) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_bool', "This method is deprecated, please use match expressions with Stdlib::Compat::Bool instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_bool", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_float.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_float.rb new file mode 100644 index 00000000..c91aa5d5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_float.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_float) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_float', "This method is deprecated, please use match expressions with Stdlib::Compat::Float instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_float", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ip_address.rb new file mode 100644 index 00000000..4c72037f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ip_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_ip_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_ip_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ip_address instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ip_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb new file mode 100644 index 00000000..97b01ae7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_ipv4_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv4 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ipv4_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb new file mode 100644 index 00000000..be0c98a8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_ipv6_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv6 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ipv6_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_numeric.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_numeric.rb new file mode 100644 index 00000000..f5e9d412 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_numeric.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_numeric) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_numeric', "This method is deprecated, please use match expressions with Stdlib::Compat::Numeric instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_numeric", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_string.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_string.rb new file mode 100644 index 00000000..a05a7963 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/is_string.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:is_string) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'is_string', "This method is deprecated, please use match expressions with Stdlib::Compat::String instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_string", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/type_of.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/type_of.rb new file mode 100644 index 00000000..01f1f49e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/type_of.rb @@ -0,0 +1,19 @@ +# 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. +# +# The built-in type() function in puppet is generally preferred over this function +# this function is provided for backwards compatibility. +Puppet::Functions.create_function(:type_of) do + def type_of(value) + Puppet::Pops::Types::TypeCalculator.infer_set(value) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb new file mode 100644 index 00000000..a3c696d0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_absolute_path) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_absolute_path', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_absolute_path", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_array.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_array.rb new file mode 100644 index 00000000..f59c6b44 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_array.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_array) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_array', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_array", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_bool.rb new file mode 100644 index 00000000..5cfb2acc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_bool.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_bool) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_bool', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_bool", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_hash.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_hash.rb new file mode 100644 index 00000000..89ad9ab5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_hash.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_hash) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_hash', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_hash", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_integer.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_integer.rb new file mode 100644 index 00000000..475ea0fa --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_integer.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_integer) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_integer', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_integer", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ip_address.rb new file mode 100644 index 00000000..1521c089 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ip_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_ip_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_ip_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ip_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb new file mode 100644 index 00000000..fe66ab3b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_ipv4_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_ipv4_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ipv4_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb new file mode 100644 index 00000000..7cc3cbdd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_ipv6_address) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_ipv6_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ipv6_address", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_legacy.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_legacy.rb new file mode 100644 index 00000000..c9d1f561 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_legacy.rb @@ -0,0 +1,62 @@ +Puppet::Functions.create_function(:validate_legacy) do + # The function checks a value against both the target_type (new) and the previous_validation function (old). + + dispatch :validate_legacy do + param 'Any', :scope + param 'Type', :target_type + param 'String', :function_name + param 'Any', :value + repeated_param 'Any', :args + end + + 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) + if assert_type(target_type, value) + if previous_validation(scope, function_name, value, *prev_args) + # Silently passes + else + Puppet.notice("Accepting previously invalid value for target type '#{target_type}'") + end + else + inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) + error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{function_name})", target_type, inferred_type) + if previous_validation(scope, function_name, value, *prev_args) + call_function('deprecation', 'validate_legacy', error_msg) + else + call_function('fail', error_msg) + end + end + end + + def previous_validation(scope, function_name, value, *prev_args) + # Call the previous validation function and catch any errors. Return true if no errors are thrown. + begin + scope.send("function_#{function_name}".to_s, [value, *prev_args]) + true + rescue Puppet::ParseError + false + end + end + + def assert_type(type, value) + Puppet::Pops::Types::TypeCalculator.instance?(type, value) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_numeric.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_numeric.rb new file mode 100644 index 00000000..3052d351 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_numeric.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_numeric) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_numeric', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_numeric", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_re.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_re.rb new file mode 100644 index 00000000..19443a8a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_re.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_re) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_re', "This method is deprecated, please use the stdlib validate_legacy function, with Pattern[]. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_re", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_slength.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_slength.rb new file mode 100644 index 00000000..584232ac --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_slength.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_slength) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_slength', "This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_slength", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_string.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_string.rb new file mode 100644 index 00000000..91ff0046 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/functions/validate_string.rb @@ -0,0 +1,15 @@ +Puppet::Functions.create_function(:validate_string) do + dispatch :deprecation_gen do + param 'Any', :scope + 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 deprecation_gen(scope, *args) + call_function('deprecation', 'validate_string', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_string", args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/abs.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/abs.rb new file mode 100644 index 00000000..11d2d7fe --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/abs.rb @@ -0,0 +1,36 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2array.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2array.rb new file mode 100644 index 00000000..e71407e8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2array.rb @@ -0,0 +1,33 @@ +# +# 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 + ) do |arguments| + + if arguments.empty? + return [] + end + + 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 + end + + return arguments + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2bool.rb new file mode 100644 index 00000000..f0f8f83d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/any2bool.rb @@ -0,0 +1,55 @@ +# +# any2bool.rb +# + +module Puppet::Parser::Functions + newfunction(:any2bool, :type => :rvalue, :doc => <<-EOS +This 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 + EOS + ) do |arguments| + + raise(Puppet::ParseError, "any2bool(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size < 1 + + # If argument is already Boolean, return it + if !!arguments[0] == arguments[0] + return arguments[0] + end + + arg = arguments[0] + + if arg == nil + return false + end + + if arg == :undef + return false + end + + valid_float = !!Float(arg) rescue false + + if arg.is_a?(Numeric) + return function_num2bool( [ arguments[0] ] ) + end + + if arg.is_a?(String) + if valid_float + return function_num2bool( [ arguments[0] ] ) + else + return function_str2bool( [ arguments[0] ] ) + end + end + + return true + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/assert_private.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/assert_private.rb new file mode 100644 index 00000000..66c79cce --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/assert_private.rb @@ -0,0 +1,29 @@ +# +# assert_private.rb +# + +module Puppet::Parser::Functions + newfunction(:assert_private, :doc => <<-'EOS' + Sets the current class or definition as private. + Calling the class or definition from outside the current module will fail. + EOS + ) do |args| + + 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 + message = args[0] + else + manifest_name = scope.source.name + manifest_type = scope.source.type + message = (manifest_type.to_s == 'hostclass') ? 'Class' : 'Definition' + message += " #{manifest_name} is private" + end + raise(Puppet::ParseError, message) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/base64.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/base64.rb new file mode 100644 index 00000000..a8998f22 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/base64.rb @@ -0,0 +1,68 @@ +module Puppet::Parser::Functions + + newfunction(:base64, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| + + Base64 encode or decode a string based on the command and the string submitted + + Usage: + + $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) + + ENDHEREDOC + + require 'base64' + + raise Puppet::ParseError, ("base64(): Wrong number of arguments (#{args.length}; must be >= 2)") unless args.length >= 2 + + actions = ['encode','decode'] + + unless actions.include?(args[0]) + raise Puppet::ParseError, ("base64(): the first argument must be one of 'encode' or 'decode'") + end + + unless args[1].is_a?(String) + raise Puppet::ParseError, ("base64(): the second argument must be a string to base64") + end + + method = ['default','strict','urlsafe'] + + if args.length <= 2 + chosenMethod = 'default' + else + chosenMethod = args[2] + end + + unless method.include?(chosenMethod) + raise Puppet::ParseError, ("base64(): the third argument must be one of 'default', 'strict', or 'urlsafe'") + end + + case args[0] + when 'encode' + case chosenMethod + when 'default' + result = Base64.encode64(args[1]) + when 'strict' + result = Base64.strict_encode64(args[1]) + when 'urlsafe' + result = Base64.urlsafe_encode64(args[1]) + end + when 'decode' + case chosenMethod + 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/basename.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/basename.rb new file mode 100644 index 00000000..f7e44384 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/basename.rb @@ -0,0 +1,34 @@ +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 + + 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 + + unless arguments[1].is_a?(String) + raise(Puppet::ParseError, 'basename(): Requires string as second argument') + end + + rv = File.basename(arguments[0], arguments[1]) + end + + end + + return rv + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2num.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2num.rb new file mode 100644 index 00000000..6ad6cf4e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2num.rb @@ -0,0 +1,26 @@ +# +# bool2num.rb +# + +module Puppet::Parser::Functions + newfunction(:bool2num, :type => :rvalue, :doc => <<-EOS + 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 + + value = function_str2bool([arguments[0]]) + + # We have real boolean values as well ... + result = value ? 1 : 0 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2str.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2str.rb new file mode 100644 index 00000000..7e364747 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/bool2str.rb @@ -0,0 +1,45 @@ +# +# 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 + 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 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 + + value = arguments[0] + true_string = arguments[1] || 'true' + false_string = arguments[2] || 'false' + 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 + + unless [true_string, false_string].all?{|x| x.kind_of?(String)} + raise(Puppet::ParseError, "bool2str(): Requires strings to convert to" ) + end + + return value ? true_string : false_string + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/camelcase.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/camelcase.rb new file mode 100644 index 00000000..d7f43f7a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/camelcase.rb @@ -0,0 +1,33 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/capitalize.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/capitalize.rb new file mode 100644 index 00000000..98b2d16c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/capitalize.rb @@ -0,0 +1,33 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ceiling.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ceiling.rb new file mode 100644 index 00000000..5f3b10b8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ceiling.rb @@ -0,0 +1,25 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chomp.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chomp.rb new file mode 100644 index 00000000..c55841e3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chomp.rb @@ -0,0 +1,34 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chop.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chop.rb new file mode 100644 index 00000000..b24ab785 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/chop.rb @@ -0,0 +1,36 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/clamp.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/clamp.rb new file mode 100644 index 00000000..432c7c1f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/clamp.rb @@ -0,0 +1,30 @@ +# +# clamp.rb +# + +module Puppet::Parser::Functions + newfunction(:clamp, :type => :rvalue, :arity => -2, :doc => <<-EOS + Clamps value to a range. + EOS + ) 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 value =~ /^\d+$/ + 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{ |n| n.to_i }.sort[1] + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/concat.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/concat.rb new file mode 100644 index 00000000..91edb4e2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/concat.rb @@ -0,0 +1,41 @@ +# +# concat.rb +# + +module Puppet::Parser::Functions + newfunction(:concat, :type => :rvalue, :doc => <<-EOS +Appends the contents of multiple arrays into array 1. + +*Example:* + + concat(['1','2','3'],['4','5','6'],['7','8','9']) + +Would result in: + + ['1','2','3','4','5','6','7','8','9'] + EOS + ) 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 + + 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 + + result = a + arguments.shift + + arguments.each do |x| + result = result + (x.is_a?(Array) ? x : [x]) + end + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/convert_base.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/convert_base.rb new file mode 100644 index 00000000..0fcbafea --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/convert_base.rb @@ -0,0 +1,35 @@ +module Puppet::Parser::Functions + + newfunction(:convert_base, :type => :rvalue, :arity => 2, :doc => <<-'ENDHEREDOC') do |args| + + Converts a given integer or base 10 string representing an integer to a specified base, as a string. + + Usage: + + $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" + + ENDHEREDOC + + 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)) + + 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 + + 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 + + number_to_convert = args[0] + new_base = args[1] + + 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 + + return number_to_convert.to_s(new_base) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/count.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/count.rb new file mode 100644 index 00000000..52de1b8a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/count.rb @@ -0,0 +1,22 @@ +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| + + if (args.size > 2) then + raise(ArgumentError, "count(): Wrong number of arguments "+ + "given #{args.size} for 1 or 2.") + end + + collection, item = args + + if item then + collection.count item + else + collection.count { |obj| obj != nil && obj != :undef && obj != '' } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb new file mode 100644 index 00000000..6df32e9c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb @@ -0,0 +1,44 @@ +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. + + For example: + + $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." + + ENDHEREDOC + + if args.length < 2 + raise Puppet::ParseError, ("deep_merge(): wrong number of arguments (#{args.length}; must be at least 2)") + end + + deep_merge = Proc.new 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 + new_value + end + end + end + + result = Hash.new + args.each do |arg| + next if arg.is_a? String and 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 + + result = deep_merge.call(result, arg) + end + return( result ) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb new file mode 100644 index 00000000..99687aee --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb @@ -0,0 +1,38 @@ +# 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. + +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, } + } +ENDOFDOC +) do |vals| + reference, params = vals + raise(ArgumentError, 'Must specify a reference') unless reference + if (! params) || params == '' + params = {} + end + ret = false + if resource = findresource(reference.to_s) + matches = params.collect do |key, value| + # eql? avoids bugs caused by monkeypatching in puppet + resource_is_undef = resource[key].eql?(:undef) || resource[key].nil? + value_is_undef = value.eql?(:undef) || value.nil? + (resource_is_undef && value_is_undef) || (resource[key] == value) + end + ret = params.empty? || !matches.include?(false) + end + Puppet.debug("Resource #{reference} was not determined to be defined") + ret +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete.rb new file mode 100644 index 00000000..466c55c9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete.rb @@ -0,0 +1,45 @@ +# +# delete.rb +# + +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. + +*Examples:* + + 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' + EOS + ) 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}.") + end + end + collection + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_at.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_at.rb new file mode 100644 index 00000000..3eb4b537 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_at.rb @@ -0,0 +1,49 @@ +# +# delete_at.rb +# + +module Puppet::Parser::Functions + newfunction(:delete_at, :type => :rvalue, :doc => <<-EOS +Deletes a determined indexed value from an array. + +*Examples:* + + delete_at(['a','b','c'], 1) + +Would return: ['a','c'] + EOS + ) do |arguments| + + 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 + + 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 + + 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 + + result.delete_at(index) # We ignore the element that got deleted ... + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb new file mode 100644 index 00000000..d72b3e9f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb @@ -0,0 +1,45 @@ +# +# delete_regex.rb +# + +module Puppet::Parser::Functions + newfunction(:delete_regex, :type => :rvalue, :doc => <<-EOS +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. + +*Examples:* + + 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} + + EOS + ) 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb new file mode 100644 index 00000000..f94d4da8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:delete_undef_values, :type => :rvalue, :doc => <<-EOS +Returns a copy of input hash or array with all undefs deleted. + +*Examples:* + + $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]) + +Would return: ['A','',false] + + EOS + ) do |args| + + raise(Puppet::ParseError, + "delete_undef_values(): Wrong number of arguments given " + + "(#{args.size})") if args.size < 1 + + 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} + elsif result.is_a?(Array) + result.delete :undef + end + result + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_values.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_values.rb new file mode 100644 index 00000000..f6c8c0e6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/delete_values.rb @@ -0,0 +1,26 @@ +module Puppet::Parser::Functions + newfunction(:delete_values, :type => :rvalue, :doc => <<-EOS +Deletes all instances of a given value from a hash. + +*Examples:* + + delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B') + +Would return: {'a'=>'A','c'=>'C','B'=>'D'} + + EOS + ) 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 } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deprecation.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deprecation.rb new file mode 100644 index 00000000..cd64fe24 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/deprecation.rb @@ -0,0 +1,17 @@ +module Puppet::Parser::Functions + newfunction(:deprecation, :doc => <<-EOS + Function to print deprecation warnings (this is the 3.X version of it), The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method.). +EOS + ) do |arguments| + + raise(Puppet::ParseError, "deprecation: Wrong number of arguments " + + "given (#{arguments.size} for 2)") unless arguments.size == 2 + + key = arguments[0] + message = arguments[1] + + if ENV['STDLIB_LOG_DEPRECATIONS'] == "true" + warning("deprecation. #{key}. #{message}") + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/difference.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/difference.rb new file mode 100644 index 00000000..cd258f75 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/difference.rb @@ -0,0 +1,36 @@ +# +# 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. + +*Examples:* + + difference(["a","b","c"],["b","c","d"]) + +Would return: ["a"] + EOS + ) do |arguments| + + # Two arguments are required + 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 + + result = first - second + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig.rb new file mode 100644 index 00000000..34fa701c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig.rb @@ -0,0 +1,16 @@ +# +# dig.rb +# + +module Puppet::Parser::Functions + newfunction(:dig, :type => :rvalue, :doc => <<-EOS + DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version. + EOS + ) do |arguments| + warning("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.") + if ! Puppet::Parser::Functions.autoloader.loaded?(:dig44) + Puppet::Parser::Functions.autoloader.load(:dig44) + end + function_dig44(arguments) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig44.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig44.rb new file mode 100644 index 00000000..1e7c318c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dig44.rb @@ -0,0 +1,73 @@ +# +# dig44.rb +# + +module Puppet::Parser::Functions + newfunction( + :dig44, + :type => :rvalue, + :arity => -2, + :doc => <<-eos +DEPRECATED: This function has been replaced in puppet 4.5.0. + +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 = dig44($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. + +In addition to the required "key" argument, the function accepts a 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 |arguments| + # Two arguments are required + raise(Puppet::ParseError, "dig44(): Wrong number of arguments " + + "given (#{arguments.size} for at least 2)") if arguments.size < 2 + + data, path, default = *arguments + + unless data.is_a?(Hash) or data.is_a?(Array) + raise(Puppet::ParseError, "dig44(): first argument must be a hash or an array, " << + "given #{data.class.name}") + end + + unless path.is_a? Array + raise(Puppet::ParseError, "dig44(): second argument must be an array, " << + "given #{path.class.name}") + end + + value = path.reduce(data) do |structure, key| + if structure.is_a? Hash or structure.is_a? Array + if structure.is_a? Array + key = Integer key rescue break + end + break if structure[key].nil? or structure[key] == :undef + structure[key] + else + break + end + end + value.nil? ? default : value + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dirname.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dirname.rb new file mode 100644 index 00000000..40b300d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dirname.rb @@ -0,0 +1,21 @@ +module Puppet::Parser::Functions + newfunction(:dirname, :type => :rvalue, :doc => <<-EOS + Returns the dirname of a path. + EOS + ) do |arguments| + + 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 File.dirname(arguments[0]) + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb new file mode 100644 index 00000000..ccac8993 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb @@ -0,0 +1,15 @@ +# 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. + Takes a single string argument. + EOS + ) do |arguments| + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'dos2unix(): Requires string as argument') + end + + arguments[0].gsub(/\r\n/, "\n") + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/downcase.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/downcase.rb new file mode 100644 index 00000000..040b84f5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/downcase.rb @@ -0,0 +1,32 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/empty.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/empty.rb new file mode 100644 index 00000000..b5a3cdea --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/empty.rb @@ -0,0 +1,31 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb new file mode 100644 index 00000000..80ffc3ac --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb @@ -0,0 +1,45 @@ +# +# enclose_ipv6.rb +# + +module Puppet::Parser::Functions + newfunction(:enclose_ipv6, :type => :rvalue, :doc => <<-EOS +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. + EOS + ) do |arguments| + + require 'ipaddr' + + rescuable_exceptions = [ ArgumentError ] + if defined?(IPAddr::InvalidAddressError) + rescuable_exceptions << IPAddr::InvalidAddressError + end + + if (arguments.size != 1) then + raise(Puppet::ParseError, "enclose_ipv6(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + unless arguments[0].is_a?(String) or arguments[0].is_a?(Array) then + raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument type "+ + "given #{arguments[0].class} expected String or Array") + end + + 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.to_s}]" if ip.ipv6? + end + result << val + end + + return result.uniq + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb new file mode 100644 index 00000000..532b7026 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb @@ -0,0 +1,46 @@ +# +# 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 + + if arguments[0].is_a?(Hash) + if arguments[1] + defaults = { 'ensure' => 'present' }.merge(arguments[1]) + else + defaults = { 'ensure' => 'present' } + end + + Puppet::Parser::Functions.function(:ensure_resources) + function_ensure_resources(['package', Hash(arguments[0]), defaults ]) + else + 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 +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb new file mode 100644 index 00000000..1ba6a447 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb @@ -0,0 +1,46 @@ +# 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. + + 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 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'}) + +ENDOFDOC +) 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 + + items.each do |item| + Puppet::Parser::Functions.function(:defined_with_params) + if function_defined_with_params(["#{type}[#{item}]", params]) + Puppet.debug("Resource #{type}[#{item}] with params #{params} not created because it already exists") + else + Puppet.debug("Create new resource #{type}[#{item}] with params #{params}") + Puppet::Parser::Functions.function(:create_resources) + function_create_resources([type.capitalize, { item => params }]) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb new file mode 100644 index 00000000..b3c51e65 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb @@ -0,0 +1,54 @@ +require 'puppet/parser/functions' + +Puppet::Parser::Functions.newfunction(:ensure_resources, + :type => :statement, + :doc => <<-'ENDOFDOC' +Takes a resource type, title (only hash), and a list of attributes that describe a +resource. + + 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'}) + +ENDOFDOC +) do |vals| + type, title, params = vals + raise(ArgumentError, 'Must specify a type') unless type + raise(ArgumentError, 'Must specify a title') unless title + params ||= {} + + if title.is_a?(Hash) + resource_hash = title.dup + resources = resource_hash.keys + + Puppet::Parser::Functions.function(:ensure_resource) + resources.each { |resource_name| + if resource_hash[resource_name] + params_merged = params.merge(resource_hash[resource_name]) + else + params_merged = params + end + function_ensure_resource([ type, resource_name, params_merged ]) + } + else + raise(Puppet::ParseError, 'ensure_resources(): Requires second argument to be a Hash') + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/flatten.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/flatten.rb new file mode 100644 index 00000000..a1ed1832 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/flatten.rb @@ -0,0 +1,33 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/floor.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/floor.rb new file mode 100644 index 00000000..9a6f014d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/floor.rb @@ -0,0 +1,25 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb new file mode 100644 index 00000000..2bb1287e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb @@ -0,0 +1,34 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb new file mode 100644 index 00000000..b66431d1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb @@ -0,0 +1,63 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb new file mode 100644 index 00000000..1421b91f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb @@ -0,0 +1,17 @@ +module Puppet::Parser::Functions + newfunction(:get_module_path, :type =>:rvalue, :doc => <<-EOT + Returns the absolute path of the specified module for the current + environment. + + Example: + $module_path = get_module_path('stdlib') + EOT + ) 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getparam.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getparam.rb new file mode 100644 index 00000000..0a5cbe0f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getparam.rb @@ -0,0 +1,35 @@ +# 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. + +*Examples:* + + define example_resource($param) { + } + + example_resource { "example_resource_instance": + param => "param_value" + } + + getparam(Example_resource["example_resource_instance"], "param") + +Would return: param_value +ENDOFDOC +) 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 + + return '' if param.empty? + + if resource = findresource(reference.to_s) + return resource[param] unless resource[param].nil? + end + + return '' +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getvar.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getvar.rb new file mode 100644 index 00000000..3af8d481 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/getvar.rb @@ -0,0 +1,35 @@ +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 + result = nil + catch(:undefined_variable) do + result = self.lookupvar("#{args[0]}") + end + + # avoid relying on incosistent behaviour around ruby return values from catch + result + rescue Puppet::ParseError # Eat the exception if strict_variables = true is set + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/grep.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/grep.rb new file mode 100644 index 00000000..ceba9ecc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/grep.rb @@ -0,0 +1,33 @@ +# +# 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 + ) do |arguments| + + if (arguments.size != 2) then + raise(Puppet::ParseError, "grep(): Wrong number of arguments "+ + "given #{arguments.size} for 2") + end + + a = arguments[0] + pattern = Regexp.new(arguments[1]) + + a.grep(pattern) + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb new file mode 100644 index 00000000..e7627982 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb @@ -0,0 +1,71 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb new file mode 100644 index 00000000..842c8ec6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb @@ -0,0 +1,25 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb new file mode 100644 index 00000000..9ccf9024 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb @@ -0,0 +1,25 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_key.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_key.rb new file mode 100644 index 00000000..4657cc29 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/has_key.rb @@ -0,0 +1,28 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/hash.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/hash.rb new file mode 100644 index 00000000..89d0e07e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/hash.rb @@ -0,0 +1,41 @@ +# +# 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 StandardError + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/intersection.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/intersection.rb new file mode 100644 index 00000000..bfbb4bab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/intersection.rb @@ -0,0 +1,34 @@ +# +# intersection.rb +# + +module Puppet::Parser::Functions + newfunction(:intersection, :type => :rvalue, :doc => <<-EOS +This function returns an array of the intersection of two. + +*Examples:* + + 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 + ) do |arguments| + + # Two arguments are required + 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 + + result = first & second + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb new file mode 100644 index 00000000..e64777f7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb @@ -0,0 +1,50 @@ +module Puppet::Parser::Functions + newfunction(:is_absolute_path, :type => :rvalue, :arity => 1, :doc => <<-'ENDHEREDOC') do |args| + Returns boolean true if the string represents an absolute path in the filesystem. This function works + for windows and unix style paths. + + The following values will return true: + + $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' + is_absolute_path($my_path) + $my_path2 = '/var/lib/puppet' + is_absolute_path($my_path2) + $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet'] + is_absolute_path($my_path3) + $my_path4 = ['/var/lib/puppet'] + is_absolute_path($my_path4) + + The following values will return false: + + is_absolute_path(true) + is_absolute_path('../var/lib/puppet') + is_absolute_path('var/lib/puppet') + $undefined = undef + is_absolute_path($undefined) + + ENDHEREDOC + function_deprecation([:is_absolute_path, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + require 'puppet/util' + + path = args[0] + # 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 + value = (Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows)) + 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!^/! + } + value = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) + end + value + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_array.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_array.rb new file mode 100644 index 00000000..1d2c0fa7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_array.rb @@ -0,0 +1,22 @@ +# +# 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| + + function_deprecation([:is_array, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + + 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 diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_bool.rb new file mode 100644 index 00000000..83d2ebe4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_bool.rb @@ -0,0 +1,22 @@ +# +# 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| + + function_deprecation([:is_bool, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + + 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 diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb new file mode 100644 index 00000000..90ede327 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb @@ -0,0 +1,54 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb new file mode 100644 index 00000000..4fb02290 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb @@ -0,0 +1,21 @@ +# +# is_email_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_email_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid email address. + EOS + ) do |arguments| + if arguments.size != 1 + raise(Puppet::ParseError, 'is_email_address(): Wrong number of arguments '\ + "given #{arguments.size} for 1") + end + + # Taken from http://emailregex.com/ (simpler regex) + valid_email_regex = %r{\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z} + return (arguments[0] =~ valid_email_regex) == 0 + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_float.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_float.rb new file mode 100644 index 00000000..1186458e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_float.rb @@ -0,0 +1,32 @@ +# +# 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| + + function_deprecation([:is_float, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb new file mode 100644 index 00000000..6da82c8c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb @@ -0,0 +1,26 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_hash.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_hash.rb new file mode 100644 index 00000000..ad907f08 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_hash.rb @@ -0,0 +1,22 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_integer.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_integer.rb new file mode 100644 index 00000000..e04fd1ff --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_integer.rb @@ -0,0 +1,47 @@ +# +# 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| + + function_deprecation([:is_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb new file mode 100644 index 00000000..5f1d765f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb @@ -0,0 +1,34 @@ +# +# 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' + + function_deprecation([:is_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb new file mode 100644 index 00000000..1764e61d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb @@ -0,0 +1,30 @@ +# +# is_ipv4_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_ipv4_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid IPv4 address. + EOS + ) do |arguments| + + require 'ipaddr' + + function_deprecation([:is_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + + if (arguments.size != 1) then + raise(Puppet::ParseError, "is_ipv4_address(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + + begin + ip = IPAddr.new(arguments[0]) + rescue ArgumentError + return false + end + + return ip.ipv4? + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb new file mode 100644 index 00000000..7ca49974 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb @@ -0,0 +1,30 @@ +# +# is_ipv6_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_ipv6_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid IPv6 address. + EOS + ) do |arguments| + + function_deprecation([:is_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + + require 'ipaddr' + + if (arguments.size != 1) then + raise(Puppet::ParseError, "is_ipv6_address(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + + begin + ip = IPAddr.new(arguments[0]) + rescue ArgumentError + return false + end + + return ip.ipv6? + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb new file mode 100644 index 00000000..2619d44a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb @@ -0,0 +1,27 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb new file mode 100644 index 00000000..4a55225e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb @@ -0,0 +1,75 @@ +# +# 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| + + function_deprecation([:is_numeric, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + + 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 diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_string.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_string.rb new file mode 100644 index 00000000..31ee91e3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/is_string.rb @@ -0,0 +1,29 @@ +# +# 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| + + function_deprecation([:is_string, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + + raise(Puppet::ParseError, "is_string(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size < 1 + + type = arguments[0] + + # when called through the v4 API shim, undef gets translated to nil + result = type.is_a?(String) || type.nil? + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join.rb new file mode 100644 index 00000000..6c0a6ba0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join.rb @@ -0,0 +1,41 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb new file mode 100644 index 00000000..e3baf9f5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb @@ -0,0 +1,56 @@ +# +# join.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 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. + +*Examples:* + + join_keys_to_values({'a'=>1,'b'=>2}, " is ") + +Would result in: ["a is 1","b is 2"] + + join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ") + +Would result in: ["a is 1","b is 2","b is 3"] + EOS + ) 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 + + # 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 + + # 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 + + # Join the keys to their values. + hash.map do |k,v| + if v.is_a?(Array) + v.map { |va| String(k) + separator + String(va) } + else + String(k) + separator + String(v) + end + end.flatten + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/keys.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/keys.rb new file mode 100644 index 00000000..f0d13b64 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/keys.rb @@ -0,0 +1,26 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb new file mode 100644 index 00000000..c9b84885 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb @@ -0,0 +1,24 @@ +module Puppet::Parser::Functions + newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-EOT + EOT + ) do |args| + 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) + if metadata_exists + metadata = PSON.load(File.read(metadata_json)) + else + if allow_empty_metadata + metadata = {} + else + raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") + end + end + + return metadata + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadjson.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadjson.rb new file mode 100644 index 00000000..3a3372b9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadjson.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:loadjson, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| +Load a JSON file containing an array, string, or hash, and return the data +in the corresponding native data type. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +For example: + + $myhash = loadjson('/etc/puppet/data/myhash.json') + $myhash = loadjson('no-file.json', {'default' => 'value'}) + ENDHEREDOC + + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + + if File.exists?(args[0]) + begin + content = File.read(args[0]) + PSON::load(content) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb new file mode 100644 index 00000000..96963624 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:loadyaml, :type => :rvalue, :arity => -2, :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 second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +For example: + + $myhash = loadyaml('/etc/puppet/data/myhash.yaml') + $myhash = loadyaml('no-file.yaml', {'default' => 'value'}) + ENDHEREDOC + + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + require 'yaml' + + if File.exists?(args[0]) + begin + YAML::load_file(args[0]) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/lstrip.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/lstrip.rb new file mode 100644 index 00000000..624e4c84 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/lstrip.rb @@ -0,0 +1,32 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/max.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/max.rb new file mode 100644 index 00000000..60fb94ac --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/max.rb @@ -0,0 +1,21 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/member.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/member.rb new file mode 100644 index 00000000..1e5b3def --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/member.rb @@ -0,0 +1,62 @@ +# +# member.rb +# + +# TODO(Krzysztof Wilczynski): We need to add support for regular expression ... +# TODO(Krzysztof Wilczynski): Support for strings and hashes too ... + +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 + ) do |arguments| + + 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 + + if arguments[1].is_a? String or arguments[1].is_a? Fixnum + item = [arguments[1]] + else + item = arguments[1] + end + + + 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? + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/merge.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/merge.rb new file mode 100644 index 00000000..1b39f206 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/merge.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:merge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| + Merges two or more hashes together and returns the resulting hash. + + For 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 will "win." + + ENDHEREDOC + + if args.length < 2 + raise Puppet::ParseError, ("merge(): wrong number of arguments (#{args.length}; must be at least 2)") + end + + # The hash we accumulate into + accumulator = Hash.new + # 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 + accumulator.merge!(arg) + end + # Return the fully merged hash + accumulator + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/min.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/min.rb new file mode 100644 index 00000000..6bd6ebf2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/min.rb @@ -0,0 +1,21 @@ +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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/num2bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/num2bool.rb new file mode 100644 index 00000000..af0e6ed7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/num2bool.rb @@ -0,0 +1,43 @@ +# +# 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| + + raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + number = arguments[0] + + case number + when Numeric + # Yay, it's a number + when String + begin + number = Float(number) + rescue ArgumentError => ex + raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number: #{ex.message}") + end + else + begin + number = number.to_s + rescue NoMethodError => ex + raise(Puppet::ParseError, "num2bool(): Unable to parse argument: #{ex.message}") + end + end + + # Truncate Floats + number = number.to_i + + # Return true for any positive number and false otherwise + return number > 0 + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parsejson.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parsejson.rb new file mode 100644 index 00000000..f7c2896e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parsejson.rb @@ -0,0 +1,29 @@ +# +# 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. + +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 + ) 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 StandardError => e + if arguments[1] + arguments[1] + else + raise e + end + end + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb new file mode 100644 index 00000000..ba9d98aa --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb @@ -0,0 +1,33 @@ +# +# 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. + +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 + ) 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] + # 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 + if arguments[1] + arguments[1] + else + raise e + end + end + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick.rb new file mode 100644 index 00000000..fdd0aefd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick.rb @@ -0,0 +1,29 @@ +module Puppet::Parser::Functions + newfunction(:pick, :type => :rvalue, :doc => <<-EOS + +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: + + $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. + +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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick_default.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick_default.rb new file mode 100644 index 00000000..36e33abf --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pick_default.rb @@ -0,0 +1,35 @@ +module Puppet::Parser::Functions + newfunction(:pick_default, :type => :rvalue, :doc => <<-EOS + +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. + +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') + +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. + +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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/prefix.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/prefix.rb new file mode 100644 index 00000000..ac1c58a5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/prefix.rb @@ -0,0 +1,52 @@ +# +# 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. + +*Examples:* + + prefix(['a','b','c'], 'p') + +Will return: ['pa','pb','pc'] + EOS + ) 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 + + 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 + + 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 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/private.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/private.rb new file mode 100644 index 00000000..3b00ba12 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/private.rb @@ -0,0 +1,17 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb new file mode 100644 index 00000000..41d42238 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb @@ -0,0 +1,56 @@ +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. + + 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. + + 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 + else + password.crypt(salt) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/range.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/range.rb new file mode 100644 index 00000000..d690df7d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/range.rb @@ -0,0 +1,87 @@ +# +# 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:* + + 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"] +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. + +Passing a third argument will cause the generated range to step by that +interval, e.g. + + range("0", "9", "2") + +Will return: [0,2,4,6,8] + EOS + ) do |arguments| + + raise(Puppet::ParseError, 'range(): Wrong number of ' + + 'arguments given (0 for 1)') if arguments.size == 0 + + if arguments.size > 1 + start = arguments[0] + stop = arguments[1] + step = arguments[2].nil? ? 1 : arguments[2].to_i.abs + + type = '..' # Use the simplest type of Range available in Ruby + + else # arguments.size == 1 + value = arguments[0] + + if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) + 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}") + 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+$/) + start = start.to_i + stop = stop.to_i + else + start = start.to_s + stop = stop.to_s + end + + range = case type + when /^(\.\.|\-)$/ then (start .. stop) + when '...' then (start ... stop) # Exclusive of last element + end + + result = range.step(step).to_a + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb new file mode 100644 index 00000000..477ee874 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb @@ -0,0 +1,31 @@ +# +# regexpescape.rb +# +module Puppet::Parser::Functions + newfunction(:regexpescape, :type => :rvalue, :doc => <<-EOS + Regexp escape a string or array of strings. + Requires either a single string or an array as an input. + EOS + ) do |arguments| # rubocop:disable Style/ClosingParenthesisIndentation + raise(Puppet::ParseError, 'regexpescape(): 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, 'regexpescape(): Requires either ' \ + 'array or string to work with') + end + + result = if value.is_a?(Array) + # Numbers in Puppet are often string-encoded which is troublesome ... + value.collect { |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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reject.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reject.rb new file mode 100644 index 00000000..1953ffcf --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reject.rb @@ -0,0 +1,31 @@ +# +# 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. + +*Examples:* + + reject(['aaa','bbb','ccc','aaaddd'], 'aaa') + +Would return: + + ['bbb','ccc'] +EOS + + if (args.size != 2) + raise Puppet::ParseError, + "reject(): Wrong number of arguments given #{args.size} for 2" + end + + ary = args[0] + pattern = Regexp.new(args[1]) + + ary.reject { |e| e =~ pattern } + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reverse.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reverse.rb new file mode 100644 index 00000000..7f1018f6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/reverse.rb @@ -0,0 +1,27 @@ +# +# reverse.rb +# + +module Puppet::Parser::Functions + newfunction(:reverse, :type => :rvalue, :doc => <<-EOS +Reverses the order of a string or array. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "reverse(): 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, 'reverse(): Requires either ' + + 'array or string to work with') + end + + result = value.reverse + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/rstrip.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/rstrip.rb new file mode 100644 index 00000000..0cf8d222 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/rstrip.rb @@ -0,0 +1,31 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb new file mode 100644 index 00000000..44e27b8d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb @@ -0,0 +1,22 @@ +Puppet::Parser::Functions::newfunction( + :seeded_rand, + :arity => 2, + :type => :rvalue, + :doc => <<-EOS +Usage: `seeded_rand(MAX, SEED)`. MAX must be a positive integer; SEED is any string. + +Generates a random whole number greater than or equal to 0 and less +than MAX, using the value of SEED for repeatable randomness. If SEED +starts with "$fqdn:", this is behaves the same as `fqdn_rand`. + +EOS +) do |args| + require 'digest/md5' + + raise(ArgumentError, "seeded_rand(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 + raise(ArgumentError, "seeded_rand(): second argument must be a string") unless args[1].is_a? String + + max = args[0].to_i + seed = Digest::MD5.hexdigest(args[1]).hex + Puppet::Util.deterministic_rand(seed,max) +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb new file mode 100644 index 00000000..447fe35d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb @@ -0,0 +1,30 @@ +# +# shell_escape.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_escape, :type => :rvalue, :doc => <<-EOS +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. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_escape(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + # explicit conversion to string is required for ruby 1.9 + string = arguments[0].to_s + + result = Shellwords.shellescape(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_join.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_join.rb new file mode 100644 index 00000000..05aeb952 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_join.rb @@ -0,0 +1,31 @@ +# +# shell_join.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_join, :type => :rvalue, :doc => <<-EOS +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 + EOS + ) 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 { |item| item.to_s } + result = Shellwords.shelljoin(array) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_split.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_split.rb new file mode 100644 index 00000000..04464481 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shell_split.rb @@ -0,0 +1,26 @@ +# +# shell_split.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_split, :type => :rvalue, :doc => <<-EOS +Splits a string into an array of tokens in the same way the Bourne shell does. + +This function behaves the same as ruby's Shellwords.shellsplit() function + EOS + ) 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shuffle.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shuffle.rb new file mode 100644 index 00000000..30c663db --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/shuffle.rb @@ -0,0 +1,45 @@ +# +# shuffle.rb +# + +module Puppet::Parser::Functions + newfunction(:shuffle, :type => :rvalue, :doc => <<-EOS +Randomizes the order of a string or array elements. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shuffle(): 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, 'shuffle(): 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 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 + + elements = result.size + + # Simple implementation of Fisher–Yates in-place shuffle ... + elements.times do |i| + j = rand(elements - i) + i + result[j], result[i] = result[i], result[j] + end + + result = string ? result.join : result + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/size.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/size.rb new file mode 100644 index 00000000..0d6cc961 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/size.rb @@ -0,0 +1,46 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/sort.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/sort.rb new file mode 100644 index 00000000..cefbe546 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/sort.rb @@ -0,0 +1,27 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/squeeze.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/squeeze.rb new file mode 100644 index 00000000..81fadfdb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/squeeze.rb @@ -0,0 +1,36 @@ +# +# 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| + + 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 + + item = arguments[0] + squeezeval = arguments[1] + + if item.is_a?(Array) then + if squeezeval then + item.collect { |i| i.squeeze(squeezeval) } + else + item.collect { |i| i.squeeze } + end + else + if squeezeval then + item.squeeze(squeezeval) + else + item.squeeze + end + end + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2bool.rb new file mode 100644 index 00000000..472506dc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2bool.rb @@ -0,0 +1,46 @@ +# +# 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| + + raise(Puppet::ParseError, "str2bool(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size < 1 + + string = arguments[0] + + # If string is already Boolean, return it + if !!string == string + return string + end + + unless string.is_a?(String) + raise(Puppet::ParseError, 'str2bool(): Requires ' + + 'string to work with') + end + + # 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 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb new file mode 100644 index 00000000..7fe7b012 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb @@ -0,0 +1,32 @@ +# +# str2saltedsha512.rb +# + +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 + ) do |arguments| + require 'digest/sha2' + + 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 + + seedint = rand(2**31 - 1) + seedstring = Array(seedint).pack("L") + saltedpass = Digest::SHA512.digest(seedstring + password) + (seedstring + saltedpass).unpack('H*')[0] + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strftime.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strftime.rb new file mode 100644 index 00000000..0b52adec --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strftime.rb @@ -0,0 +1,107 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strip.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strip.rb new file mode 100644 index 00000000..3fac47d5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/strip.rb @@ -0,0 +1,38 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/suffix.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/suffix.rb new file mode 100644 index 00000000..29084340 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/suffix.rb @@ -0,0 +1,53 @@ +# +# suffix.rb +# + +module Puppet::Parser::Functions + newfunction(:suffix, :type => :rvalue, :doc => <<-EOS +This function applies a suffix to all elements in an array, or to the keys +in a hash. + +*Examples:* + + suffix(['a','b','c'], 'p') + +Will return: ['ap','bp','cp'] + EOS + ) 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 + + enumerable = arguments[0] + + unless enumerable.is_a?(Array) or enumerable.is_a?(Hash) + raise Puppet::ParseError, "suffix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" + end + + 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 + + if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + result = enumerable.collect do |i| + i = i.to_s + suffix ? i + suffix : i + end + else + result = Hash[enumerable.map do |k,v| + k = k.to_s + [ suffix ? k + suffix : k, v ] + end] + end + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/swapcase.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/swapcase.rb new file mode 100644 index 00000000..eb7fe137 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/swapcase.rb @@ -0,0 +1,38 @@ +# +# swapcase.rb +# + +module Puppet::Parser::Functions + newfunction(:swapcase, :type => :rvalue, :doc => <<-EOS +This function will swap the existing case of a string. + +*Examples:* + + swapcase("aBcD") + +Would result in: "AbCd" + EOS + ) do |arguments| + + raise(Puppet::ParseError, "swapcase(): 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, '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 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/time.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/time.rb new file mode 100644 index 00000000..c5747474 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/time.rb @@ -0,0 +1,50 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb new file mode 100644 index 00000000..df490ea8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb @@ -0,0 +1,31 @@ +module Puppet::Parser::Functions + newfunction(:to_bytes, :type => :rvalue, :doc => <<-EOS + Converts the argument into bytes, for example 4 kB becomes 4096. + 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 + ) do |arguments| + + 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 = 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 + else raise Puppet::ParseError, "to_bytes(): Unknown prefix #{prefix}" + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb new file mode 100644 index 00000000..fc19a230 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb @@ -0,0 +1,53 @@ +module Puppet::Parser::Functions + newfunction( + :try_get_value, + :type => :rvalue, + :arity => -2, + :doc => <<-eos +DEPRECATED: this function is deprecated, please use dig() instead. + +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| + warning("try_get_value() DEPRECATED: this function is deprecated, please use dig() instead.") + data = args[0] + path = args[1] || '' + default = args[2] + + if !(data.is_a?(Hash) || data.is_a?(Array)) || path == '' + return default || data + end + + separator = args[3] || '/' + path = path.split(separator).map{ |key| key =~ /^\d+$/ ? key.to_i : key } + function_dig([data, path, default]) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type.rb new file mode 100644 index 00000000..016529b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type.rb @@ -0,0 +1,19 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type3x.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type3x.rb new file mode 100644 index 00000000..0800b4a3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/type3x.rb @@ -0,0 +1,51 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/union.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/union.rb new file mode 100644 index 00000000..6c5bb834 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/union.rb @@ -0,0 +1,29 @@ +# +# union.rb +# + +module Puppet::Parser::Functions + newfunction(:union, :type => :rvalue, :doc => <<-EOS +This function returns a union of two or more arrays. + +*Examples:* + + union(["a","b","c"],["b","c","d"]) + +Would return: ["a","b","c","d"] + EOS + ) 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 + + arguments.each do |argument| + raise(Puppet::ParseError, 'union(): Every parameter must be an array') unless argument.is_a?(Array) + end + + arguments.reduce(:|) + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unique.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unique.rb new file mode 100644 index 00000000..cf770f3b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unique.rb @@ -0,0 +1,50 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb new file mode 100644 index 00000000..0bd9cd1f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb @@ -0,0 +1,15 @@ +# 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. + Takes a single string argument. + EOS + ) do |arguments| + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'unix2dos(): Requires string as argument') + end + + arguments[0].gsub(/\r*\n/, "\r\n") + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/upcase.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/upcase.rb new file mode 100644 index 00000000..44b3bcd6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/upcase.rb @@ -0,0 +1,45 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/uriescape.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/uriescape.rb new file mode 100644 index 00000000..45bbed22 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/uriescape.rb @@ -0,0 +1,34 @@ +# +# uriescape.rb +# +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 + ) do |arguments| + + raise(Puppet::ParseError, "uriescape(): 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, '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 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb new file mode 100644 index 00000000..c73f3dfe --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb @@ -0,0 +1,54 @@ +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 + + # The deprecation function was being called twice, as validate_absolute_path calls is_absolute_path. I have removed it from here so it only calls deprecation once within is_absolute_path. + # function_deprecation([:validate_absolute_path, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + + 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 paths within the candidates array + candidates.each do |path| + unless function_is_absolute_path([path]) + raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_array.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_array.rb new file mode 100644 index 00000000..3bf39835 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_array.rb @@ -0,0 +1,35 @@ +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 + + function_deprecation([:validate_array, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb new file mode 100644 index 00000000..2196c3e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb @@ -0,0 +1,83 @@ +require 'tempfile' + +module Puppet::Parser::Functions + newfunction(:validate_augeas, :doc => <<-'ENDHEREDOC') do |args| + 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 + 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. + + For example, 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: + + 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') + + ENDHEREDOC + 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.") + 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 + + msg = args[3] || "validate_augeas(): Failed to validate content against #{args[1].inspect}" + + require 'augeas' + aug = Augeas::open(nil, nil, Augeas::NO_MODL_AUTOLOAD) + begin + content = args[0] + + # Test content in a temporary file + tmpfile = Tempfile.new("validate_augeas") + begin + tmpfile.write(content) + ensure + tmpfile.close + end + + # Check for syntax + lens = args[1] + aug.transform( + :lens => 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) + end + + # Launch unit tests + tests = args[2] || [] + aug.defvar('file', "/files#{tmpfile.path}") + tests.each do |t| + msg += " testing path #{t}" + raise Puppet::ParseError, (msg) unless aug.match(t).empty? + end + ensure + aug.close + tmpfile.unlink + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb new file mode 100644 index 00000000..49075b83 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb @@ -0,0 +1,37 @@ +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 + + # The deprecation function was being called twice, as validate_bool calls is_bool. I have removed it from here so it only calls deprecation once within is_bool. + # function_deprecation([:validate_bool, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb new file mode 100644 index 00000000..685162b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb @@ -0,0 +1,63 @@ +require 'puppet/util/execution' +require 'tempfile' + +module Puppet::Parser::Functions + newfunction(:validate_cmd, :doc => <<-'ENDHEREDOC') do |args| + 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. + + A helpful error message can be returned like this: + + Example: + + # 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') + + 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 + + msg = args[2] || "validate_cmd(): failed to validate content with command #{args[1].inspect}" + + content = args[0] + checkscript = args[1] + + # Test content in a temporary file + 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 + + 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}" + raise Puppet::ParseError, msg + rescue StandardError => detail + msg += "\n#{detail.class.name} #{detail}" + raise Puppet::ParseError, msg + ensure + tmpfile.unlink + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb new file mode 100644 index 00000000..ddd0d25f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb @@ -0,0 +1,31 @@ +module Puppet::Parser::Functions + newfunction(:validate_email_address, :doc => <<-ENDHEREDOC + Validate that all values passed are valid email addresses. + Fail compilation if any value fails this check. + The following values will pass: + $my_email = "waldo@gmail.com" + validate_email_address($my_email) + validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) + + The following values will fail, causing compilation to abort: + $some_array = [ 'bad_email@/d/efdf.com' ] + validate_email_address($some_array) + ENDHEREDOC + ) do |args| + rescuable_exceptions = [ArgumentError] + + if args.empty? + raise Puppet::ParseError, "validate_email_address(): wrong number of arguments (#{args.length}; must be > 0)" + end + + args.each do |arg| + raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String) + + begin + raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" unless function_is_email_address([arg]) + rescue *rescuable_exceptions + raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb new file mode 100644 index 00000000..fcdc7e1d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb @@ -0,0 +1,35 @@ +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 + + function_deprecation([:validate_hash, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb new file mode 100644 index 00000000..2ae02931 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb @@ -0,0 +1,134 @@ +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 + + function_deprecation([:validate_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + + # 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb new file mode 100644 index 00000000..5d80cfbe --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb @@ -0,0 +1,52 @@ +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_ip_address("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_ip_address("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 ] + + function_deprecation([:validate_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb new file mode 100644 index 00000000..0660abdf --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb @@ -0,0 +1,50 @@ +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| + + function_deprecation([:validate_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb new file mode 100644 index 00000000..f5dd9e50 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb @@ -0,0 +1,51 @@ +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| + + function_deprecation([:validate_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb new file mode 100644 index 00000000..4205b30d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb @@ -0,0 +1,96 @@ +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 + + function_deprecation([:validate_numeric, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + + # 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_re.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_re.rb new file mode 100644 index 00000000..0ac83ddc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_re.rb @@ -0,0 +1,50 @@ +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 + + function_deprecation([:validate_re, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Re. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb new file mode 100644 index 00000000..383855c7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb @@ -0,0 +1,71 @@ +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 + + function_deprecation([:validate_slength, 'This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.']) + + 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_string.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_string.rb new file mode 100644 index 00000000..6675d86d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_string.rb @@ -0,0 +1,41 @@ +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 + + function_deprecation([:validate_string, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + + unless args.length > 0 then + raise Puppet::ParseError, ("validate_string(): wrong number of arguments (#{args.length}; must be > 0)") + end + + args.each do |arg| + # when called through the v4 API shim, undef gets translated to nil + unless arg.is_a?(String) || arg.nil? + raise Puppet::ParseError, ("#{arg.inspect} is not a string. It looks to be a #{arg.class}") + end + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb new file mode 100644 index 00000000..fc9f23ff --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb @@ -0,0 +1,47 @@ +module Puppet::Parser::Functions + + newfunction(:validate_x509_rsa_key_pair, :doc => <<-ENDHEREDOC + 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. + + Fail compilation if any value fails this check. + + validate_x509_rsa_key_pair($cert, $key) + + ENDHEREDOC + ) do |args| + + require 'openssl' + + NUM_ARGS = 2 unless defined? NUM_ARGS + + unless args.length == NUM_ARGS then + raise Puppet::ParseError, + ("validate_x509_rsa_key_pair(): wrong number of arguments (#{args.length}; must be #{NUM_ARGS})") + end + + args.each do |arg| + unless arg.is_a?(String) + raise Puppet::ParseError, "#{arg.inspect} is not a string." + end + 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 + + unless cert.verify(key) + raise Puppet::ParseError, "Certificate signature does not match supplied key" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values.rb new file mode 100644 index 00000000..16067561 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values.rb @@ -0,0 +1,39 @@ +# +# 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/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values_at.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values_at.rb new file mode 100644 index 00000000..f350f539 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/values_at.rb @@ -0,0 +1,99 @@ +# +# values_at.rb +# + +module Puppet::Parser::Functions + newfunction(:values_at, :type => :rvalue, :doc => <<-EOS +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: + +* A single numeric index +* A range in the form of 'start-stop' (eg. 4-9) +* An array combining the above + +*Examples*: + + 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']. + EOS + ) 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 + + 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 + + result = [] + indices_list = [] + + indices.each do |i| + i = i.to_s + if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/) + 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 + + range = case type + when /^(\.\.|\-)$/ then (start .. stop) + when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ... + end + + range.each { |i| indices_list << i.to_i } + else + # Only positive numbers allowed in this case ... + if not i.match(/^\d+$/) + raise(Puppet::ParseError, 'values_at(): Unknown format ' + + 'of given index') + end + + # 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 + + 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 + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/zip.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/zip.rb new file mode 100644 index 00000000..3074f282 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/parser/functions/zip.rb @@ -0,0 +1,39 @@ +# +# 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:* + + zip(['1','2','3'],['4','5','6']) + +Would result in: + + ["1", "4"], ["2", "5"], ["3", "6"] + EOS + ) 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 + + 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 + + flatten = function_str2bool([arguments[2]]) if arguments[2] + + result = a.zip(b) + result = flatten ? result.flatten : result + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/provider/file_line/ruby.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/provider/file_line/ruby.rb new file mode 100644 index 00000000..beeb4308 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/provider/file_line/ruby.rb @@ -0,0 +1,132 @@ +Puppet::Type.type(:file_line).provide(:ruby) do + def exists? + if resource[:replace].to_s != 'true' and count_matches(match_regex) > 0 + true + else + lines.find do |line| + if resource[:ensure].to_s == 'absent' and resource[:match_for_absence].to_s == 'true' + line.chomp =~ Regexp.new(resource[:match]) + else + line.chomp == resource[:line].chomp + end + end + 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 + end + end + + def destroy + if resource[:match_for_absence].to_s == 'true' and resource[:match] + handle_destroy_with_match + else + handle_destroy_line + end + 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]) + end + + def match_regex + resource[:match] ? Regexp.new(resource[:match]) : nil + end + + def handle_create_with_match() + regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil + 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 + + 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 + end + end + + if (match_count == 0) + fh.puts(resource[:line]) + end + end + end + + def handle_create_with_after + regex = Regexp.new(resource[:after]) + count = count_matches(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." + 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 + end + end + + if (count == 0) # append the line to the end of the file + append_line + end + end + + def count_matches(regex) + lines.select{|l| l.match(regex)}.size + end + + def handle_destroy_with_match + 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 + + local_lines = lines + File.open(resource[:path],'w') do |fh| + fh.write(local_lines.reject{|l| match_regex.match(l) }.join('')) + end + 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 + end + + ## + # append the line to the file. + # + # @api private + def append_line + File.open(resource[:path], 'w') do |fh| + lines.each do |l| + fh.puts(l) + end + fh.puts resource[:line] + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/anchor.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/anchor.rb new file mode 100644 index 00000000..fe1e5aa1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/anchor.rb @@ -0,0 +1,46 @@ +Puppet::Type.newtype(:anchor) do + desc <<-'ENDOFDESC' + A simple resource type intended to be used as an anchor in a composite class. + + 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': } + + ENDOFDESC + + newparam :name do + 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 + # chain of propagation. + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/file_line.rb b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/file_line.rb new file mode 100644 index 00000000..7b7d44ee --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/lib/puppet/type/file_line.rb @@ -0,0 +1,125 @@ +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', + } + + 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. + EOT + + ensurable do + defaultvalues + defaultto :present + end + + 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.' + 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.' + + ' 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' + 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)' + + ' This is also takes a regex.' + end + + newparam(:line) do + desc 'The line to be appended to the file or used to replace matches found by the match attribute.' + end + + newparam(:path) do + desc 'The file Puppet will ensure contains the line specified by the line parameter.' + validate do |value| + unless Puppet::Util.absolute_path?(value) + raise Puppet::Error, "File paths must be fully qualified, not '#{value}'" + end + end + end + + newparam(:replace) do + desc 'If true, replace line that matches. If false, do not write line if a match is 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] + unless (self[:ensure].to_s == 'absent') and (self[:match_for_absence].to_s == 'true') and self[:match] + raise(Puppet::Error, "line is a required attribute") + end + end + unless self[:path] + raise(Puppet::Error, "path is a required attribute") + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/manifests/init.pp b/tools/laptop_puppetisation/modules/stdlib/manifests/init.pp new file mode 100644 index 00000000..9ea22a73 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/manifests/init.pp @@ -0,0 +1,18 @@ +# 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 +# +class stdlib { + include ::stdlib::stages +} diff --git a/tools/laptop_puppetisation/modules/stdlib/manifests/stages.pp b/tools/laptop_puppetisation/modules/stdlib/manifests/stages.pp new file mode 100644 index 00000000..7de254c7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/manifests/stages.pp @@ -0,0 +1,43 @@ +# 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. +# +# The high level stages are (in order): +# +# * setup +# * main +# * runtime +# * setup_infra +# * deploy_infra +# * setup_app +# * 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' } +# } +# +class stdlib::stages { + + stage { 'setup': before => Stage['main'] } + stage { 'runtime': require => Stage['main'] } + -> stage { 'setup_infra': } + -> stage { 'deploy_infra': } + -> stage { 'setup_app': } + -> stage { 'deploy_app': } + -> stage { 'deploy': } + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/metadata.json b/tools/laptop_puppetisation/modules/stdlib/metadata.json new file mode 100644 index 00000000..52f545b4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/metadata.json @@ -0,0 +1,112 @@ +{ + "name": "puppetlabs-stdlib", + "version": "4.14.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", + "dependencies": [ + + ], + "data_provider": null, + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "4", + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "10 SP4", + "11 SP1", + "12" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7", + "8" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04" + ] + }, + { + "operatingsystem": "Solaris", + "operatingsystemrelease": [ + "10", + "11", + "12" + ] + }, + { + "operatingsystem": "Windows", + "operatingsystemrelease": [ + "Server 2003", + "Server 2003 R2", + "Server 2008", + "Server 2008 R2", + "Server 2012", + "Server 2012 R2", + "7", + "8" + ] + }, + { + "operatingsystem": "AIX", + "operatingsystemrelease": [ + "5.3", + "6.1", + "7.1" + ] + } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">=2.7.20 <5.0.0" + } + ], + "description": "Standard Library for Puppet Modules" +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/abs_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/abs_spec.rb new file mode 100755 index 00000000..6e41e2fd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/abs_spec.rb @@ -0,0 +1,30 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/anchor_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/anchor_spec.rb new file mode 100755 index 00000000..5bc2bbb3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/anchor_spec.rb @@ -0,0 +1,26 @@ +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 + class anchored { + anchor { 'anchored::begin': } + ~> anchor { 'anchored::end': } + } + + class anchorrefresh { + notify { 'first': } + ~> class { 'anchored': } + ~> anchor { 'final': } + } + + include anchorrefresh + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Anchor\[final\]: Triggered 'refresh'/) + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/any2array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/any2array_spec.rb new file mode 100755 index 00000000..18ea4cd9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/any2array_spec.rb @@ -0,0 +1,49 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/base64_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/base64_spec.rb new file mode 100755 index 00000000..97e1738e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/base64_spec.rb @@ -0,0 +1,18 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/bool2num_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/bool2num_spec.rb new file mode 100755 index 00000000..52ff75bc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/bool2num_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/build_csv.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/build_csv.rb new file mode 100755 index 00000000..62ecbf13 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/build_csv.rb @@ -0,0 +1,83 @@ +#!/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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/capitalize_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/capitalize_spec.rb new file mode 100755 index 00000000..e5e7b7bf --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/capitalize_spec.rb @@ -0,0 +1,33 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ceiling_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ceiling_spec.rb new file mode 100755 index 00000000..557986eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ceiling_spec.rb @@ -0,0 +1,39 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chomp_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chomp_spec.rb new file mode 100755 index 00000000..f6c15956 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chomp_spec.rb @@ -0,0 +1,21 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chop_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chop_spec.rb new file mode 100755 index 00000000..a16a7102 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/chop_spec.rb @@ -0,0 +1,45 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/clamp_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/clamp_spec.rb new file mode 100755 index 00000000..0189258d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/clamp_spec.rb @@ -0,0 +1,40 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'clamp function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'clamps list of values' do + pp = <<-EOS + $x = 17 + $y = 225 + $z = 155 + $o = clamp($x, $y, $z) + if $o == $z { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'clamps array of values' do + pp = <<-EOS + $a = [7, 19, 66] + $b = 19 + $o = clamp($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 no arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/concat_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/concat_spec.rb new file mode 100755 index 00000000..c472db6b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/concat_spec.rb @@ -0,0 +1,54 @@ +#! /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 + it 'should concat hash arguments' do + pp = <<-EOS + $output = concat([{"a" => "b"}], {"c" => "d", "e" => "f"}) + validate_array($output) + if size($output) != 2 { + fail("${output} should have 2 elements.") + } + if $output[1] != {"c" => "d", "e" => "f"} { + fail("${output} does not have the expected hash for the second element.") + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/count_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/count_spec.rb new file mode 100755 index 00000000..fe7ca9dc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/count_spec.rb @@ -0,0 +1,30 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deep_merge_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deep_merge_spec.rb new file mode 100755 index 00000000..c0f9b126 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deep_merge_spec.rb @@ -0,0 +1,20 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/defined_with_params_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/defined_with_params_spec.rb new file mode 100755 index 00000000..fc544508 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/defined_with_params_spec.rb @@ -0,0 +1,22 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_at_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_at_spec.rb new file mode 100755 index 00000000..db0c01f7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_at_spec.rb @@ -0,0 +1,19 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_spec.rb new file mode 100755 index 00000000..a28604ce --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_spec.rb @@ -0,0 +1,19 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_undef_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_undef_values_spec.rb new file mode 100755 index 00000000..b7eda192 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_undef_values_spec.rb @@ -0,0 +1,19 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_values_spec.rb new file mode 100755 index 00000000..6d2369c3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/delete_values_spec.rb @@ -0,0 +1,25 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deprecation_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deprecation_spec.rb new file mode 100644 index 00000000..7a0b34c4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/deprecation_spec.rb @@ -0,0 +1,102 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'deprecation function' do + + if fact('operatingsystem') == 'windows' + test_file = 'C:/deprecation' + else + test_file = "/tmp/deprecation" + end + + # It seems that Windows needs everything to be on one line when using puppet apply -e, otherwise the manifests would be in an easier format + add_file_manifest = "\"deprecation('key', 'message') file { '#{test_file}': ensure => present, content => 'test', }\"" + remove_file_manifest = "file { '#{test_file}': ensure => absent }" + + before :all do + apply_manifest(remove_file_manifest) + end + + context 'with --strict=error', if: get_puppet_version =~ /^4/ do + before :all do + @result = on(default, puppet('apply', '--strict=error', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) + end + + it "should return an error" do + expect(@result.exit_code).to eq(1) + end + + it "should show the error message" do + expect(@result.stderr).to match(/deprecation. key. message/) + end + + describe file("#{test_file}") do + it { is_expected.not_to be_file } + end + end + + context 'with --strict=warning', if: get_puppet_version =~ /^4/ do + before :all do + @result = on(default, puppet('apply', '--strict=warning', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) + end + + it "should not return an error" do + expect(@result.exit_code).to eq(0) + end + + it "should show the error message" do + expect(@result.stderr).to match(/Warning: message/) + end + + describe file("#{test_file}") do + it { is_expected.to be_file } + end + end + + context 'with --strict=off', if: get_puppet_version =~ /^4/ do + before :all do + @result = on(default, puppet('apply', '--strict=off', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) + end + + it "should not return an error" do + expect(@result.exit_code).to eq(0) + end + + it "should not show the error message" do + expect(@result.stderr).not_to match(/Warning: message/) + end + + describe file("#{test_file}") do + it { is_expected.to be_file } + end + end + + context 'puppet 3 test', if: get_puppet_version =~ /^3/ do + before :all do + @result = on(default, puppet('apply', '--parser=future', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + after :all do + apply_manifest(remove_file_manifest) + end + + it "should return a deprecation error" do + expect(@result.stderr).to match(/Warning: message/) + end + it "should pass without error" do + expect(@result.exit_code).to eq(0) + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/difference_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/difference_spec.rb new file mode 100755 index 00000000..2fae5c43 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/difference_spec.rb @@ -0,0 +1,26 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/dirname_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/dirname_spec.rb new file mode 100755 index 00000000..97913ddb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/dirname_spec.rb @@ -0,0 +1,42 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/downcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/downcase_spec.rb new file mode 100755 index 00000000..bc4e7069 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/downcase_spec.rb @@ -0,0 +1,39 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/empty_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/empty_spec.rb new file mode 100755 index 00000000..2d4df901 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/empty_spec.rb @@ -0,0 +1,53 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ensure_resource_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ensure_resource_spec.rb new file mode 100755 index 00000000..93f25ddc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/ensure_resource_spec.rb @@ -0,0 +1,30 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'ensure_resource function' do + describe 'success' do + it 'ensures a resource already declared' do + apply_manifest('') + pp = <<-EOS + notify { "test": loglevel => 'err' } + ensure_resource('notify', 'test', { 'loglevel' => 'err' }) + EOS + + apply_manifest(pp, :expect_changes => true) + end + + it 'ensures a undeclared resource' do + apply_manifest('') + pp = <<-EOS + ensure_resource('notify', 'test', { 'loglevel' => 'err' }) + EOS + + apply_manifest(pp, :expect_changes => true) + end + it 'takes defaults arguments' + end + describe 'failure' do + it 'handles no arguments' + it 'handles non strings' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/flatten_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/flatten_spec.rb new file mode 100755 index 00000000..c4d66e04 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/flatten_spec.rb @@ -0,0 +1,39 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/floor_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/floor_spec.rb new file mode 100755 index 00000000..0dcdad9c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/floor_spec.rb @@ -0,0 +1,39 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rand_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rand_string_spec.rb new file mode 100644 index 00000000..065a5172 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rand_string_spec.rb @@ -0,0 +1,66 @@ +#! /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|9Acvnhkt4J)"/) + 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|2383756694)"/) + 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|1jJtAMs94d)"/) + 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|7100592312)"/) + end + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles non-numbers for length argument' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rotate_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rotate_spec.rb new file mode 100755 index 00000000..404351f6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/fqdn_rotate_spec.rb @@ -0,0 +1,64 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/get_module_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/get_module_path_spec.rb new file mode 100755 index 00000000..6ac690c1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/get_module_path_spec.rb @@ -0,0 +1,27 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getparam_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getparam_spec.rb new file mode 100755 index 00000000..b1a677ec --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getparam_spec.rb @@ -0,0 +1,24 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getvar_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getvar_spec.rb new file mode 100755 index 00000000..333c467f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/getvar_spec.rb @@ -0,0 +1,26 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/grep_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/grep_spec.rb new file mode 100755 index 00000000..b39d48ec --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/grep_spec.rb @@ -0,0 +1,26 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_interface_with_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_interface_with_spec.rb new file mode 100755 index 00000000..95901930 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_interface_with_spec.rb @@ -0,0 +1,54 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_address_spec.rb new file mode 100755 index 00000000..149a10dc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_address_spec.rb @@ -0,0 +1,33 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_network_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_network_spec.rb new file mode 100755 index 00000000..7d2f34ed --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_ip_network_spec.rb @@ -0,0 +1,33 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_key_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_key_spec.rb new file mode 100755 index 00000000..c8557cbe --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/has_key_spec.rb @@ -0,0 +1,41 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/hash_spec.rb new file mode 100755 index 00000000..ed53834b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/hash_spec.rb @@ -0,0 +1,26 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/intersection_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/intersection_spec.rb new file mode 100755 index 00000000..66b86529 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/intersection_spec.rb @@ -0,0 +1,27 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_a_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_a_spec.rb new file mode 100644 index 00000000..355fd837 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_a_spec.rb @@ -0,0 +1,30 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_array_spec.rb new file mode 100755 index 00000000..9c6bad73 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_array_spec.rb @@ -0,0 +1,67 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_bool_spec.rb new file mode 100755 index 00000000..60079f95 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_bool_spec.rb @@ -0,0 +1,81 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_domain_name_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_domain_name_spec.rb new file mode 100755 index 00000000..e0f03fa8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_domain_name_spec.rb @@ -0,0 +1,83 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_float_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_float_spec.rb new file mode 100755 index 00000000..338ba58d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_float_spec.rb @@ -0,0 +1,86 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_function_available_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_function_available_spec.rb new file mode 100755 index 00000000..2b5dd6d1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_function_available_spec.rb @@ -0,0 +1,58 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_hash_spec.rb new file mode 100755 index 00000000..2ef310ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_hash_spec.rb @@ -0,0 +1,63 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_integer_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_integer_spec.rb new file mode 100755 index 00000000..bf6902b9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_integer_spec.rb @@ -0,0 +1,95 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ip_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ip_address_spec.rb new file mode 100755 index 00000000..ed7a8543 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ip_address_spec.rb @@ -0,0 +1,80 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv4_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv4_address_spec.rb new file mode 100755 index 00000000..5dc6bf53 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv4_address_spec.rb @@ -0,0 +1,52 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'is_ipv4_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'is_ipv4_addresss' do + pp = <<-EOS + $a = '1.2.3.4' + $b = true + $o = is_ipv4_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_ipv4_addresss strings' do + pp = <<-EOS + $a = "aoeu" + $b = false + $o = is_ipv4_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_ipv4_addresss ipv4 out of range' do + pp = <<-EOS + $a = '1.2.3.400' + $b = false + $o = is_ipv4_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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv6_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv6_address_spec.rb new file mode 100755 index 00000000..1e88be86 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_ipv6_address_spec.rb @@ -0,0 +1,66 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'is_ipv6_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'is_ipv6_addresss' do + pp = <<-EOS + $a = "fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74" + $b = true + $o = is_ipv6_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_ipv6_addresss ipv6 compressed' do + pp = <<-EOS + $a = "fe00::1" + $b = true + $o = is_ipv6_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_ipv6_addresss strings' do + pp = <<-EOS + $a = "aoeu" + $b = false + $o = is_ipv6_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_ipv6_addresss ip out of range' do + pp = <<-EOS + $a = 'fe80:0000:cd12:d123:e2f8:47ff:fe09:gggg' + $b = false + $o = is_ipv6_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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_mac_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_mac_address_spec.rb new file mode 100755 index 00000000..a2c892f4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_mac_address_spec.rb @@ -0,0 +1,38 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_numeric_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_numeric_spec.rb new file mode 100755 index 00000000..21c89884 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_numeric_spec.rb @@ -0,0 +1,95 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_string_spec.rb new file mode 100755 index 00000000..f526888d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/is_string_spec.rb @@ -0,0 +1,113 @@ +#! /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 + it 'is_strings undef' do + pp = <<-EOS + $a = undef + $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 + end + describe 'failure' do + it 'handles improper argument counts' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_keys_to_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_keys_to_values_spec.rb new file mode 100755 index 00000000..70493fd5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_keys_to_values_spec.rb @@ -0,0 +1,24 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_spec.rb new file mode 100755 index 00000000..5397ce2c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/join_spec.rb @@ -0,0 +1,26 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/keys_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/keys_spec.rb new file mode 100755 index 00000000..176918e9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/keys_spec.rb @@ -0,0 +1,23 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadjson_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadjson_spec.rb new file mode 100644 index 00000000..2992c37d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadjson_spec.rb @@ -0,0 +1,52 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('stdlib') + +describe 'loadjson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'loadjsons array of values' do + shell("echo '{\"aaa\":1,\"bbb\":2,\"ccc\":3,\"ddd\":4}' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json') + notice(inline_template('loadjson[aaa] is <%= @o["aaa"].inspect %>')) + notice(inline_template('loadjson[bbb] is <%= @o["bbb"].inspect %>')) + notice(inline_template('loadjson[ccc] is <%= @o["ccc"].inspect %>')) + notice(inline_template('loadjson[ddd] is <%= @o["ddd"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[aaa\] is 1/) + expect(r.stdout).to match(/loadjson\[bbb\] is 2/) + expect(r.stdout).to match(/loadjson\[ccc\] is 3/) + expect(r.stdout).to match(/loadjson\[ddd\] is 4/) + end + end + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadjson('#{tmpdir}/no-file.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + end + describe 'failure' do + it 'fails with no arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadyaml_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadyaml_spec.rb new file mode 100644 index 00000000..ba3f0b78 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/loadyaml_spec.rb @@ -0,0 +1,56 @@ +#! /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 + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadyaml('#{tmpdir}/no-file.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testyaml.yaml") + pp = <<-EOS + $o = loadyaml('#{tmpdir}/testyaml.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end + end + describe 'failure' do + it 'fails with no arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/lstrip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/lstrip_spec.rb new file mode 100755 index 00000000..3dc952fb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/lstrip_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/max_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/max_spec.rb new file mode 100755 index 00000000..f04e3d28 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/max_spec.rb @@ -0,0 +1,20 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/member_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/member_spec.rb new file mode 100755 index 00000000..fe75a078 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/member_spec.rb @@ -0,0 +1,54 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/merge_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/merge_spec.rb new file mode 100755 index 00000000..227b9942 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/merge_spec.rb @@ -0,0 +1,23 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/min_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/min_spec.rb new file mode 100755 index 00000000..509092d3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/min_spec.rb @@ -0,0 +1,20 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/centos-7-x64.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 00000000..5eebdefb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: el-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/debian-8-x64.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 00000000..fef6e63c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/default.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/default.yml new file mode 100644 index 00000000..dba339c4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-1404-x64: + roles: + - agent + - default + platform: ubuntu-14.04-amd64 + hypervisor: vagrant + box: puppetlabs/ubuntu-14.04-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/centos-7.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 00000000..a3333aac --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/debian-8.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 00000000..df5c3194 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/ubuntu-14.04.yml b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/ubuntu-14.04.yml new file mode 100644 index 00000000..b1efa583 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/nodesets/docker/ubuntu-14.04.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/num2bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/num2bool_spec.rb new file mode 100755 index 00000000..1d99ba02 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/num2bool_spec.rb @@ -0,0 +1,76 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parsejson_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parsejson_spec.rb new file mode 100755 index 00000000..d0e3de84 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parsejson_spec.rb @@ -0,0 +1,55 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parseyaml_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parseyaml_spec.rb new file mode 100755 index 00000000..64511f13 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/parseyaml_spec.rb @@ -0,0 +1,58 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_default_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_default_spec.rb new file mode 100755 index 00000000..a663f54e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_default_spec.rb @@ -0,0 +1,54 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_spec.rb new file mode 100755 index 00000000..46cf63f2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pick_spec.rb @@ -0,0 +1,44 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/prefix_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/prefix_spec.rb new file mode 100755 index 00000000..de55530e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/prefix_spec.rb @@ -0,0 +1,42 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pw_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pw_hash_spec.rb new file mode 100644 index 00000000..cd4cb87c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/pw_hash_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/range_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/range_spec.rb new file mode 100755 index 00000000..a3ccd339 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/range_spec.rb @@ -0,0 +1,36 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reject_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reject_spec.rb new file mode 100755 index 00000000..7f16a008 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reject_spec.rb @@ -0,0 +1,42 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reverse_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reverse_spec.rb new file mode 100755 index 00000000..c3f01567 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/reverse_spec.rb @@ -0,0 +1,23 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/rstrip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/rstrip_spec.rb new file mode 100755 index 00000000..b57a8b04 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/rstrip_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/shuffle_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/shuffle_spec.rb new file mode 100755 index 00000000..b840d1f1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/shuffle_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/size_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/size_spec.rb new file mode 100755 index 00000000..a52b778b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/size_spec.rb @@ -0,0 +1,55 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/sort_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/sort_spec.rb new file mode 100755 index 00000000..c85bfabd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/sort_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/squeeze_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/squeeze_spec.rb new file mode 100755 index 00000000..400a458c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/squeeze_spec.rb @@ -0,0 +1,47 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2bool_spec.rb new file mode 100755 index 00000000..cf549dab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2bool_spec.rb @@ -0,0 +1,31 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2saltedsha512_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2saltedsha512_spec.rb new file mode 100755 index 00000000..993e63ba --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/str2saltedsha512_spec.rb @@ -0,0 +1,22 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strftime_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strftime_spec.rb new file mode 100755 index 00000000..53b7f903 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strftime_spec.rb @@ -0,0 +1,22 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strip_spec.rb new file mode 100755 index 00000000..906fd7ab --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/strip_spec.rb @@ -0,0 +1,34 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/suffix_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/suffix_spec.rb new file mode 100755 index 00000000..630f866d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/suffix_spec.rb @@ -0,0 +1,42 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/swapcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/swapcase_spec.rb new file mode 100755 index 00000000..b7894fbe --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/swapcase_spec.rb @@ -0,0 +1,22 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/time_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/time_spec.rb new file mode 100755 index 00000000..cdb29607 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/time_spec.rb @@ -0,0 +1,36 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/to_bytes_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/to_bytes_spec.rb new file mode 100755 index 00000000..2b4c61f4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/to_bytes_spec.rb @@ -0,0 +1,27 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/try_get_value_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/try_get_value_spec.rb new file mode 100755 index 00000000..c0bf38ae --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/try_get_value_spec.rb @@ -0,0 +1,47 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/type_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/type_spec.rb new file mode 100755 index 00000000..67e32480 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/type_spec.rb @@ -0,0 +1,37 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/union_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/union_spec.rb new file mode 100755 index 00000000..160fd7b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/union_spec.rb @@ -0,0 +1,25 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unique_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unique_spec.rb new file mode 100755 index 00000000..bfadad19 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unique_spec.rb @@ -0,0 +1,33 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unsupported_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unsupported_spec.rb new file mode 100755 index 00000000..1c559f67 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/unsupported_spec.rb @@ -0,0 +1,11 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/upcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/upcase_spec.rb new file mode 100755 index 00000000..3d2906d7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/upcase_spec.rb @@ -0,0 +1,33 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/uriescape_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/uriescape_spec.rb new file mode 100755 index 00000000..7e30205e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/uriescape_spec.rb @@ -0,0 +1,23 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_absolute_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_absolute_path_spec.rb new file mode 100755 index 00000000..7082e848 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_absolute_path_spec.rb @@ -0,0 +1,31 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_array_spec.rb new file mode 100755 index 00000000..2f549d54 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_array_spec.rb @@ -0,0 +1,37 @@ +#! /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 + [ + %{validate_array({'a' => 'hash' })}, + %{validate_array('string')}, + %{validate_array(false)}, + %{validate_array(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not an Array\. It looks to be a/) + end + end + end + describe 'failure' do + it 'handles improper number of arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_augeas_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_augeas_spec.rb new file mode 100755 index 00000000..71a4c842 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_augeas_spec.rb @@ -0,0 +1,63 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_bool_spec.rb new file mode 100755 index 00000000..5c52d0f7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_bool_spec.rb @@ -0,0 +1,37 @@ +#! /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 + [ + %{validate_bool('true')}, + %{validate_bool('false')}, + %{validate_bool([true])}, + %{validate_bool(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not a boolean\. It looks to be a/) + end + end + end + describe 'failure' do + it 'handles improper number of arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_cmd_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_cmd_spec.rb new file mode 100755 index 00000000..5ac66fdb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_cmd_spec.rb @@ -0,0 +1,52 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_hash_spec.rb new file mode 100755 index 00000000..637df0ae --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_hash_spec.rb @@ -0,0 +1,37 @@ +#! /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 + [ + %{validate_hash('{ "not" => "hash" }')}, + %{validate_hash('string')}, + %{validate_hash(["array"])}, + %{validate_hash(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(//) + end + end + end + describe 'failure' do + it 'handles improper number of arguments' + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv4_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv4_address_spec.rb new file mode 100755 index 00000000..64841c37 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv4_address_spec.rb @@ -0,0 +1,31 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv6_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv6_address_spec.rb new file mode 100755 index 00000000..6426d1a5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_ipv6_address_spec.rb @@ -0,0 +1,31 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_re_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_re_spec.rb new file mode 100755 index 00000000..22f6d47d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_re_spec.rb @@ -0,0 +1,47 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_slength_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_slength_spec.rb new file mode 100755 index 00000000..1ab2bb98 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_slength_spec.rb @@ -0,0 +1,72 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_string_spec.rb new file mode 100755 index 00000000..ae3468f7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/validate_string_spec.rb @@ -0,0 +1,43 @@ +#! /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 undef' do + pp = <<-EOS + validate_string(undef) + 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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_at_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_at_spec.rb new file mode 100755 index 00000000..da63cf30 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_at_spec.rb @@ -0,0 +1,73 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_spec.rb new file mode 100755 index 00000000..a2eff329 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/values_spec.rb @@ -0,0 +1,35 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/zip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/zip_spec.rb new file mode 100755 index 00000000..139079e3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/acceptance/zip_spec.rb @@ -0,0 +1,86 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolute_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolute_path_spec.rb new file mode 100644 index 00000000..3fb9d120 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolute_path_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::absolute_path', type: :class do + 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 |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Absolute_path/) } + end + end + end + + context 'relative paths' do + %w{ + relative1 + . + .. + ./foo + ../foo + etc/puppetlabs/puppet + opt/puppet/bin + relative\\windows + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Absolute_path/) } + end + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolutepath_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolutepath_spec.rb new file mode 100644 index 00000000..aa435d7f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/absolutepath_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::absolutepath', type: :class do + describe 'valid handling' do + %w{ + /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 + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "*/Users//nope", + "\\Users/hc/wksp/stdlib", + "C:noslashes", + "\\var\\tmp" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Variant/) } + end + end + end + + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/array_spec.rb new file mode 100644 index 00000000..d0f9877f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/array_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::array', type: :class do + describe 'accepts arrays' do + [ + [], + ['one'], + [1], + [{}], + [[]], + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + '', + 'one', + '1', + {}, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::Array/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/bool_spec.rb new file mode 100644 index 00000000..78c57fc1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/bool_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::bool', type: :class do + describe 'accepts booleans' do + [ + true, + false, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + [1], + [{}], + [true], + 'true', + 'false', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::Bool/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/float_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/float_spec.rb new file mode 100644 index 00000000..cc207583 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/float_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::float', type: :class do + describe 'accepts floats' do + [ + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3, '3', -3, '-3'].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Float or Pattern(\[.*\]+)?/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpsurl_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpsurl_spec.rb new file mode 100644 index 00000000..97ae0067 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpsurl_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::httpsurl', type: :class do + describe 'valid handling' do + %w{ + https://hello.com + https://notcreative.org + https://notexciting.co.uk + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "hptts:/nah", + "https;//notrightbutclose.org" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::HTTPSUrl/) } + end + end + end + + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpurl_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpurl_spec.rb new file mode 100644 index 00000000..8bd57ca0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/httpurl_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::httpurl', type: :class do + describe 'valid handling' do + %w{ + https://hello.com + https://notcreative.org + https://canstillaccepthttps.co.uk + http://anhttp.com + http://runningoutofideas.gov + http:// + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "hptts:/nah", + "https;//notrightbutclose.org" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::HTTPUrl/) } + end + end + end + + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/integer_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/integer_spec.rb new file mode 100644 index 00000000..260090a2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/integer_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::integer', type: :class do + describe 'accepts integers' do + [ + 3, + '3', + -3, + '-3', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3.7, '3.7',-3.7, '-342.2315e-12' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Integer, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ip_address.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ip_address.rb new file mode 100644 index 00000000..664bf24c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ip_address.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::ip_address', type: :class 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' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + 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 + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv4_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv4_spec.rb new file mode 100644 index 00000000..210b4b1a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv4_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::ipv4', type: :class do + describe 'accepts ipv4 addresses' do + SharedData::IPV4_PATTERNS.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + describe 'rejects other values' do + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Ipv4/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv6_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv6_spec.rb new file mode 100644 index 00000000..13d7c3e4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/ipv6_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::ipv6', type: :class do + describe 'accepts ipv6 addresses' do + [ + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + describe 'rejects other values' do + [ + 'nope', + '77', + '4.4.4', + '2000:7334' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Ipv6/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/numeric_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/numeric_spec.rb new file mode 100644 index 00000000..0e98bee7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/numeric_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::numeric', type: :class do + describe 'accepts numerics' do + [ + 3, + '3', + -3, + '-3', + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Numeric, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/string_spec.rb new file mode 100644 index 00000000..8a93585d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/string_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::string', type: :class do + describe 'accepts strings' do + [ + '', + 'one', + nil, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + [], + {}, + 1, + true, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a String/) } + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/unixpath_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/unixpath_spec.rb new file mode 100644 index 00000000..aee161de --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/unixpath_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::unixpath', type: :class do + describe 'valid handling' do + %w{ + /usr2/username/bin:/usr/local/bin:/usr/bin:. + /var/tmp + /Users/helencampbell/workspace/puppetlabs-stdlib + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "C:/whatever", + "\\var\\tmp", + "\\Users/hc/wksp/stdlib", + "*/Users//nope" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Unixpath/) } + end + end + end + + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/aliases/windowspath_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/windowspath_spec.rb new file mode 100644 index 00000000..c13794e2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/aliases/windowspath_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::windowspath', type: :class do + describe 'valid handling' do + %w{ + C:\\ + C:\\WINDOWS\\System32 + C:/windows/system32 + X:/foo/bar + X:\\foo\\bar + \\\\host\\windows + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "/usr2/username/bin:/usr/local/bin:/usr/bin:.", + "C;//notright/here", + "C:noslashes" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Windowspath/) } + end + end + end + + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/dscacheutil/root b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/dscacheutil/root new file mode 100644 index 00000000..1e34519b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/dscacheutil/root @@ -0,0 +1,8 @@ +name: root +password: * +uid: 0 +gid: 0 +dir: /var/root +shell: /bin/bash +gecos: rawr Root + diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/lsuser/root b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/lsuser/root new file mode 100644 index 00000000..afd59ca4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/lsuser/root @@ -0,0 +1,2 @@ +#name:home +root:/root diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolute_path.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolute_path.pp new file mode 100644 index 00000000..d77f6bde --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolute_path.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Absolute_path type alias +class test::absolute_path( + Stdlib::Compat::Absolute_path $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolutepath.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolutepath.pp new file mode 100644 index 00000000..83214711 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/absolutepath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Absolutepath type. Not to be confused with Stdlib::Compat::Absolute_path. +class test::absolutepath( + Stdlib::Absolutepath $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/array.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/array.pp new file mode 100644 index 00000000..84b6a5b6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/array.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Array type alias +class test::array( + Stdlib::Compat::Array $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/bool.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/bool.pp new file mode 100644 index 00000000..ab5b5ea1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/bool.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Bool type alias +class test::bool( + Stdlib::Compat::Bool $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/float.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/float.pp new file mode 100644 index 00000000..03a603d5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/float.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Float type alias +class test::float( + Stdlib::Compat::Float $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpsurl.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpsurl.pp new file mode 100644 index 00000000..9d6b92de --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpsurl.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::HTTPSUrl type alias +class test::httpsurl( + Stdlib::HTTPSUrl $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpurl.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpurl.pp new file mode 100644 index 00000000..abf869ea --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/httpurl.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::HTTPUrl type alias +class test::httpurl( + Stdlib::HTTPUrl $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/integer.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/integer.pp new file mode 100644 index 00000000..a4f26df4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/integer.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Integer type alias +class test::integer( + Stdlib::Compat::Integer $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ip_address.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ip_address.pp new file mode 100644 index 00000000..bbbd8045 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ip_address.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ip_address type alias +class test::ip_address( + Stdlib::Compat::Ip_address $value, + ) { + notice("Success") + } diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv4.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv4.pp new file mode 100644 index 00000000..2e8022d5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv4.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ipv4 type alias +class test::ipv4( + Stdlib::Compat::Ipv4 $value, + ) { + notice("Success") + } diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv6.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv6.pp new file mode 100644 index 00000000..7912fd6f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/ipv6.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ipv6 type alias +class test::ipv6( + Stdlib::Compat::Ipv6 $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/numeric.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/numeric.pp new file mode 100644 index 00000000..2657ebc7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/numeric.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Numeric type alias +class test::numeric( + Stdlib::Compat::Numeric $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/string.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/string.pp new file mode 100644 index 00000000..6508c70d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/string.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::String type alias +class test::string( + Stdlib::Compat::String $value, + ) { + + notice("Success") + +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/unixpath.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/unixpath.pp new file mode 100644 index 00000000..93111091 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/unixpath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Unixpath type alias +class test::unixpath( + Stdlib::Unixpath $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/windowspath.pp b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/windowspath.pp new file mode 100644 index 00000000..af93ed3f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/fixtures/test/manifests/windowspath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Windowspath type alias +class test::windowspath( + Stdlib::Windowspath $value, + ) { + notice("Success") +} diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/abs_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/abs_spec.rb new file mode 100755 index 00000000..7d2257b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/abs_spec.rb @@ -0,0 +1,30 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2array_spec.rb new file mode 100755 index 00000000..70121f1e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2array_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "any2array" do + it { is_expected.not_to eq(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('one', 'two').and_return(['one', 'two']) } + 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 { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key', 'value']) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2bool_spec.rb new file mode 100755 index 00000000..9d351cea --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/any2bool_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'any2bool' 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).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/tools/laptop_puppetisation/modules/stdlib/spec/functions/assert_private_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/assert_private_spec.rb new file mode 100755 index 00000000..355e0dd3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/assert_private_spec.rb @@ -0,0 +1,41 @@ +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') + + is_expected.to run.with_params() + end + end + + context "when called from private class" do + before :each do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + end + + it "should fail with a class error message" do + scope.source.expects(:name).returns('foo::baz') + scope.source.expects(:type).returns('hostclass') + + is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Class foo::baz is private/) + end + + context "with an explicit failure message" do + it { is_expected.to run.with_params('failure message!').and_raise_error(Puppet::ParseError, /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') + + is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Definition foo::baz is private/) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/base64_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/base64_spec.rb new file mode 100755 index 00000000..842a37a9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/base64_spec.rb @@ -0,0 +1,37 @@ +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").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", "three").and_raise_error(Puppet::ParseError, /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 { 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", "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n").and_return("a very long string that will cause the base64 encoder to produce output with multiple lines") } + it { is_expected.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 { is_expected.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 { is_expected.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 { is_expected.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 { is_expected.to run.with_params("encode", "https://www.google.com.tw/?gws_rd=ssl#q=hello+world", "urlsafe").and_return("aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk") } + it { is_expected.to run.with_params("decode", "aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk", "urlsafe").and_return("https://www.google.com.tw/?gws_rd=ssl#q=hello+world") } + + it { is_expected.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 { is_expected.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/tools/laptop_puppetisation/modules/stdlib/spec/functions/basename_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/basename_spec.rb new file mode 100755 index 00000000..c84e192b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/basename_spec.rb @@ -0,0 +1,14 @@ +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.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') } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2num_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2num_spec.rb new file mode 100755 index 00000000..e5068594 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2num_spec.rb @@ -0,0 +1,14 @@ +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) } + + [ true, 'true', 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| + it { is_expected.to run.with_params(falsey).and_return(0) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2str_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2str_spec.rb new file mode 100755 index 00000000..23a754ba --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/bool2str_spec.rb @@ -0,0 +1,17 @@ +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.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") } + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/camelcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/camelcase_spec.rb new file mode 100755 index 00000000..c78aa62f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/camelcase_spec.rb @@ -0,0 +1,17 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/capitalize_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/capitalize_spec.rb new file mode 100755 index 00000000..7ce2e163 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/capitalize_spec.rb @@ -0,0 +1,15 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/ceiling_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ceiling_spec.rb new file mode 100755 index 00000000..567426fd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ceiling_spec.rb @@ -0,0 +1,13 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/chomp_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/chomp_spec.rb new file mode 100755 index 00000000..68787429 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/chomp_spec.rb @@ -0,0 +1,20 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/chop_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/chop_spec.rb new file mode 100755 index 00000000..db7d18b8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/chop_spec.rb @@ -0,0 +1,20 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/clamp_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/clamp_spec.rb new file mode 100644 index 00000000..3e2fe7ac --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/clamp_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'clamp' 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([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(12, 88, 71, 190).and_raise_error(Puppet::ParseError, /Wrong number of arguments, need three to clamp/) } + it { is_expected.to run.with_params('12string', 88, 15).and_raise_error(Puppet::ParseError, /Required explicit numeric/) } + it { is_expected.to run.with_params(1, 2, {'a' => 55}).and_raise_error(Puppet::ParseError, /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/tools/laptop_puppetisation/modules/stdlib/spec/functions/concat_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/concat_spec.rb new file mode 100755 index 00000000..eb762338 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/concat_spec.rb @@ -0,0 +1,25 @@ +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.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([{"a" => "b"}], {"c" => "d", "e" => "f"}).and_return([{"a" => "b"}, {"c" => "d", "e" => "f"}]) } + + 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) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/convert_base_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/convert_base_spec.rb new file mode 100644 index 00000000..8ab22845 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/convert_base_spec.rb @@ -0,0 +1,24 @@ +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 "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/) + 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/) + 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(5, 2).and_return('101') } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/count_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/count_spec.rb new file mode 100755 index 00000000..c8d19601 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/count_spec.rb @@ -0,0 +1,18 @@ +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 { + pending("should actually be like this, and not like above") + is_expected.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) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/deep_merge_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/deep_merge_spec.rb new file mode 100755 index 00000000..397e048c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/deep_merge_spec.rb @@ -0,0 +1,55 @@ +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_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'}) } + + 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'}) + end + it { is_expected.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 { is_expected.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'}}}) + } + end + + it 'should not change the original hashes' do + argument1 = { 'key1' => 'value1' } + original1 = argument1.dup + argument2 = { 'key2' => 'value2' } + original2 = argument2.dup + + subject.call([argument1, argument2]) + expect(argument1).to eq(original1) + expect(argument2).to eq(original2) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/defined_with_params_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/defined_with_params_spec.rb new file mode 100755 index 00000000..e2f3abe3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/defined_with_params_spec.rb @@ -0,0 +1,35 @@ +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) } + 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) } + 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) } + end + + describe 'when passing undef values' do + let :pre_condition do + 'file { "/tmp/a": ensure => present }' + end + + 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 }).and_return(true) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_at_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_at_spec.rb new file mode 100755 index 00000000..0e19472e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_at_spec.rb @@ -0,0 +1,28 @@ +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 { + pending("Current implementation ignores parameters after the first two.") + is_expected.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) } + 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 "should leave the original array intact" do + argument = [1, 2, 3] + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_regex_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_regex_spec.rb new file mode 100755 index 00000000..f27a9467 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_regex_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'delete_regex' 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') } + it { is_expected.to run.with_params({}, 'two') } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two', 'three', 'four').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } + + 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 { 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({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ + .and_return( {'key3' => 'value3'}) + } + end + + it "should leave the original array intact" do + argument1 = ['one','two','three'] + original1 = argument1.dup + subject.call([argument1,'two']) + expect(argument1).to eq(original1) + end + it "should leave the original hash intact" do + argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + original1 = argument1.dup + subject.call([argument1,'key2']) + expect(argument1).to eq(original1) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_spec.rb new file mode 100755 index 00000000..b44accfa --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_spec.rb @@ -0,0 +1,70 @@ +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') } + 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) } + + 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']) } + end + + describe 'deleting from a string' do + it { is_expected.to run.with_params('', '').and_return('') } + it { is_expected.to run.with_params('bar', '').and_return('bar') } + it { is_expected.to run.with_params('', 'bar').and_return('') } + it { is_expected.to run.with_params('bar', 'bar').and_return('') } + it { is_expected.to run.with_params('barbar', 'bar').and_return('') } + 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('barfoobar', ['barbar', 'foo']).and_return('barbar') } + it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') } + 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 { 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({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ + .and_return( {'key3' => 'value3'}) + } + end + + it "should leave the original array intact" do + argument1 = ['one','two','three'] + original1 = argument1.dup + result = subject.call([argument1,'two']) + expect(argument1).to eq(original1) + end + it "should leave the original string intact" do + argument1 = 'onetwothree' + original1 = argument1.dup + result = subject.call([argument1,'two']) + expect(argument1).to eq(original1) + end + it "should leave the original hash intact" do + argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + original1 = argument1.dup + result = subject.call([argument1,'key2']) + expect(argument1).to eq(original1) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_undef_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_undef_values_spec.rb new file mode 100755 index 00000000..ec9fb9c2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_undef_values_spec.rb @@ -0,0 +1,56 @@ +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) } + + describe 'when deleting from an array' do + [ :undef, '', nil ].each do |undef_value| + describe "when undef is represented by #{undef_value.inspect}" do + before 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 + 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']) } + end + + it "should leave the original argument intact" do + argument = ['one',undef_value,'two'] + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) + end + end + + it { is_expected.to run.with_params(['undef']).and_return(['undef']) } + end + + describe 'when deleting from a hash' do + [ :undef, '', nil ].each do |undef_value| + describe "when undef is represented by #{undef_value.inspect}" do + before 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 + 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'}) + } + end + + it "should leave the original argument intact" do + argument = { 'key1' => 'value1', 'key2' => undef_value } + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) + end + end + + it { is_expected.to run.with_params({'key' => 'undef'}).and_return({'key' => 'undef'}) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_values_spec.rb new file mode 100755 index 00000000..12907d4b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/delete_values_spec.rb @@ -0,0 +1,37 @@ +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) } + 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) } + 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 { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value to delete'}, 'value to delete') \ + .and_return({'key1' => 'value1'}) + } + it { is_expected.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 + argument = { 'key1' => 'value1', 'key2' => 'value2' } + original = argument.dup + result = subject.call([argument, 'value2']) + expect(argument).to eq(original) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/deprecation_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/deprecation_spec.rb new file mode 100644 index 00000000..cee4f1ca --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/deprecation_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'deprecation' do + before(:each) { + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + } + + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + + it 'should display a single warning' do + Puppet.expects(:warning).with(includes('heelo')) + is_expected.to run.with_params('key', 'heelo') + end + + it 'should display a single warning, despite multiple calls' do + Puppet.expects(:warning).with(includes('heelo')).once + is_expected.to run.with_params('key', 'heelo') + is_expected.to run.with_params('key', 'heelo') + end + + it 'should fail twice with message, with multiple calls. when strict= :error' do + Puppet.settings[:strict] = :error + Puppet.expects(:warning).with(includes('heelo')).never + is_expected.to run.with_params('key', 'heelo').and_raise_error(RuntimeError, /deprecation. key. heelo/) + is_expected.to run.with_params('key', 'heelo').and_raise_error(RuntimeError, /deprecation. key. heelo/) + end + + it 'should display nothing, despite multiple calls. strict= :off' do + Puppet.settings[:strict] = :off + Puppet.expects(:warning).with(includes('heelo')).never + is_expected.to run.with_params('key', 'heelo') + is_expected.to run.with_params('key', 'heelo') + end + + after(:all) { + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + } + end +else + # Puppet version < 4 will use these tests. + describe 'deprecation' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + before(:all) do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + end + 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 'should display a single warning' do + scope.expects(:warning).with(includes('heelo')) + is_expected.to run.with_params('key', 'heelo') + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/difference_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/difference_spec.rb new file mode 100755 index 00000000..d5e983d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/difference_spec.rb @@ -0,0 +1,21 @@ +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.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(['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(['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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig44_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig44_spec.rb new file mode 100644 index 00000000..4f7408d2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig44_spec.rb @@ -0,0 +1,105 @@ +require 'spec_helper' + +describe 'dig44' do + + let(:data) do + { + 'a' => { + 'g' => '2', + 'e' => [ + 'f0', + 'f1', + { + 'x' => { + 'y' => 'z' + } + }, + 'f3', + ] + }, + 'b' => true, + 'c' => false, + 'd' => '1', + 'e' => :undef, + 'f' => nil, + } + end + + context 'single values' do + it 'should exist' do + is_expected.not_to be_nil + end + + it 'should require two arguments' do + is_expected.to run.with_params().and_raise_error(ArgumentError) + end + + it 'should fail if the data is not a structure' do + is_expected.to run.with_params('test', []).and_raise_error(Puppet::Error) + end + + it 'should fail if the path is not an array' do + is_expected.to run.with_params({}, '').and_raise_error(Puppet::Error) + end + + it 'should return the value if the value is string' do + is_expected.to run.with_params(data, ['d'], 'default').and_return('1') + end + + it 'should return true if the value is true' do + is_expected.to run.with_params(data, ['b'], 'default').and_return(true) + end + + it 'should return false if the value is false' do + is_expected.to run.with_params(data, ['c'], 'default').and_return(false) + end + + it 'should return the default if the value is nil' do + is_expected.to run.with_params(data, ['f'], 'default').and_return('default') + end + + it 'should return the default if the value is :undef (same as nil)' do + is_expected.to run.with_params(data, ['e'], 'default').and_return('default') + end + + it 'should return the default if the path is not found' do + is_expected.to run.with_params(data, ['missing'], 'default').and_return('default') + end + end + + context 'structure values' do + + it 'should be able to extract a deeply nested hash value' do + is_expected.to run.with_params(data, %w(a g), 'default').and_return('2') + end + + it 'should return the default value if the path is too long' do + is_expected.to run.with_params(data, %w(a g c d), 'default').and_return('default') + end + + it 'should support an array index (number) in the path' do + is_expected.to run.with_params(data, ['a', 'e', 1], 'default').and_return('f1') + end + + it 'should support an array index (string) in the path' do + is_expected.to run.with_params(data, %w(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, %w(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, %w(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, %w(a e 2 x y), 'default').and_return('z') + end + + it 'should return "nil" if value is not found and no default value is provided' do + is_expected.to run.with_params(data, %w(a 1)).and_return(nil) + end + + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig_spec.rb new file mode 100644 index 00000000..ad16fdd4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dig_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'dig' do + + it "should exist" do + expect(Puppet::Parser::Functions.function("dig")).to eq("function_dig") + end + + it "should give a deprecation warning when called" do + scope.expects(:warning).with("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.") + scope.function_dig([{}, []]) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/dirname_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dirname_spec.rb new file mode 100755 index 00000000..46c4c35c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dirname_spec.rb @@ -0,0 +1,13 @@ +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.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') } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/dos2unix_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dos2unix_spec.rb new file mode 100644 index 00000000..9c84703c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/dos2unix_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'dos2unix' do + context 'Checking parameter validity' do + it { is_expected.not_to eq(nil) } + it do + is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + end + end + + context '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) + end + end + + context 'Converting from unix to unix format' do + sample_text = "Hello\nWorld\n" + desired_output = "Hello\nWorld\n" + + it 'should output unix format' do + should run.with_params(sample_text).and_return(desired_output) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/downcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/downcase_spec.rb new file mode 100755 index 00000000..c594560a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/downcase_spec.rb @@ -0,0 +1,15 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/empty_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/empty_spec.rb new file mode 100755 index 00000000..a3a25d6a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/empty_spec.rb @@ -0,0 +1,22 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_packages_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_packages_spec.rb new file mode 100755 index 00000000..c8247329 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_packages_spec.rb @@ -0,0 +1,36 @@ +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 + let(:pre_condition) { 'package { puppet: ensure => absent }' } + + describe 'after running ensure_package("facter")' do + before { subject.call(['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') } + end + + describe 'after running ensure_package("facter", { "provider" => "gem" })' do + before { subject.call(['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") } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_resource_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_resource_spec.rb new file mode 100755 index 00000000..d552f4ef --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/ensure_resource_spec.rb @@ -0,0 +1,93 @@ +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/) } + if Puppet.version.to_f >= 4.6 + 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) + } + + context 'given an empty catalog' do + describe 'after running ensure_resource("user", "username1", {})' do + before { subject.call(['User', 'username1', {}]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').without_ensure } + end + + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before { subject.call(['User', 'username1', { 'gid' => :undef }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').without_ensure } + it { expect(lambda { catalogue }).to contain_user('username1').without_gid } + end + + describe 'after running ensure_resource("user", "username1", { ensure => present, gid => undef })' do + before { subject.call(['User', 'username1', { 'ensure' => 'present', 'gid' => :undef }]) } + + # 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('username1').without_gid } + end + + end + + context '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', {}]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + end + + describe 'after running ensure_resource("user", "username2", {})' do + before { subject.call(['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 } + end + + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before { subject.call(['User', 'username1', { 'gid' => :undef }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + end + + describe 'after running ensure_resource("user", ["username1", "username2"], {})' do + before { subject.call(['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 } + end + + describe 'when providing already set params' do + let(:params) { { 'ensure' => 'present' } } + before { subject.call(['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) } + 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/) + } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/flatten_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/flatten_spec.rb new file mode 100755 index 00000000..a4338be4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/flatten_spec.rb @@ -0,0 +1,14 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/floor_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/floor_spec.rb new file mode 100755 index 00000000..608c602f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/floor_spec.rb @@ -0,0 +1,12 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rand_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rand_string_spec.rb new file mode 100644 index 00000000..e4070846 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rand_string_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper' + +describe '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.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") + + expect(val1).not_to eql(val2) + end + + def fqdn_rand_string(max, args = {}) + host = args[:host] || '127.0.0.1' + charset = args[:charset] + extra = args[:extra_identifier] || [] + + # 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) + + function_args = [max] + if args.has_key?(:charset) or !extra.empty? + function_args << charset + end + function_args += extra + scope.function_fqdn_rand_string(function_args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rotate_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rotate_spec.rb new file mode 100755 index 00000000..db7a7173 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/fqdn_rotate_spec.rb @@ -0,0 +1,75 @@ +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.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(['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) + 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') + 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"]) + 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"]) + 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') + expect(val1).not_to eq(val2) + end + + it "should accept 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 + end + + it "should 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 + + def fqdn_rotate(value, args = {}) + host = args[:host] || '127.0.0.1' + extra = args[:extra_identifier] || [] + + # 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) + + function_args = [value] + extra + scope.function_fqdn_rotate(function_args) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/get_module_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/get_module_path_spec.rb new file mode 100755 index 00000000..a39e413d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/get_module_path_spec.rb @@ -0,0 +1,48 @@ +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/) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) } + + 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") } + + before(:each) { Puppet[:modulepath] = modulepath } + + context 'in the default environment' do + before(:each) { Puppet::Module.expects(:find).with('foo', 'rp_env').returns(path_of_module_foo) } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + + context 'when the modulepath is a list' do + before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + end + end + + context '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) } + + context 'when the modulepath is a list' do + before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/getparam_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/getparam_spec.rb new file mode 100755 index 00000000..e4ef9e6a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/getparam_spec.rb @@ -0,0 +1,27 @@ +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/) } + + describe 'when compared against a user resource with no params' do + let(:pre_condition) { 'user { "one": }' } + + it { is_expected.to run.with_params('User[one]', 'ensure').and_return('') } + it { is_expected.to run.with_params('User[two]', 'ensure').and_return('') } + it { is_expected.to run.with_params('User[one]', 'shell').and_return('') } + end + + describe 'when compared against a user resource with params' do + let(:pre_condition) { 'user { "one": ensure => present, shell => "/bin/sh", managehome => false, }' } + + 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 { is_expected.to run.with_params('User[one]', 'managehome').and_return(false) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/getvar_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/getvar_spec.rb new file mode 100755 index 00000000..54f1842e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/getvar_spec.rb @@ -0,0 +1,23 @@ +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) } + + it { is_expected.to run.with_params('$::foo').and_return(nil) } + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/grep_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/grep_spec.rb new file mode 100755 index 00000000..6e0bd6eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/grep_spec.rb @@ -0,0 +1,19 @@ +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 { + 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/) + } + 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/) + } + 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([], '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']) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_interface_with_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_interface_with_spec.rb new file mode 100755 index 00000000..7334d38b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_interface_with_spec.rb @@ -0,0 +1,38 @@ +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) } + + # 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' } } + 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 + 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', + } + 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', '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) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_address_spec.rb new file mode 100755 index 00000000..42a5a792 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_address_spec.rb @@ -0,0 +1,22 @@ +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) } + + context "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', + } + 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) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_network_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_network_spec.rb new file mode 100755 index 00000000..7b5fe66a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_ip_network_spec.rb @@ -0,0 +1,22 @@ +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) } + + context "On Linux Systems" do + let(:facts) do + { + :interfaces => 'eth0,lo', + :network => :undefined, + :network_lo => '127.0.0.0', + :network_eth0 => '10.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) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_key_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_key_spec.rb new file mode 100755 index 00000000..965d5a65 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/has_key_spec.rb @@ -0,0 +1,15 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/hash_spec.rb new file mode 100755 index 00000000..4fe99cee --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/hash_spec.rb @@ -0,0 +1,14 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/intersection_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/intersection_spec.rb new file mode 100755 index 00000000..c0f60869 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/intersection_spec.rb @@ -0,0 +1,21 @@ +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.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.to run.with_params([], []).and_return([]) } + it { is_expected.to run.with_params([], ['one']).and_return([]) } + 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(['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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_a_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_a_spec.rb new file mode 100644 index 00000000..8dec13f5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_a_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +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) } + 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.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) + end + + it 'fails when comparing an integer and a string' do + is_expected.to run.with_params(5, String).and_return(false) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_array_spec.rb new file mode 100755 index 00000000..e89f54b7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_array_spec.rb @@ -0,0 +1,36 @@ +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) } + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(['1.2.3.4']).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(['1.2.3.4']).and_return(true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_bool_spec.rb new file mode 100755 index 00000000..d21345c2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_bool_spec.rb @@ -0,0 +1,33 @@ +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) } + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(true).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(false).and_return(true) + end + end +end + diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_domain_name_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_domain_name_spec.rb new file mode 100755 index 00000000..c1bf0e34 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_domain_name_spec.rb @@ -0,0 +1,43 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_email_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_email_address_spec.rb new file mode 100755 index 00000000..8b7b358d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_email_address_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'is_email_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('bob@gmail.com').and_return(true) } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com').and_return(true) } + it { is_expected.to run.with_params('peter.parker@gmail.com').and_return(true) } + it { is_expected.to run.with_params('1.2.3@domain').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({}).and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_float_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_float_spec.rb new file mode 100755 index 00000000..af3322e7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_float_spec.rb @@ -0,0 +1,42 @@ +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 + + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(2.2).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(1.0).and_return(true) + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_function_available.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_function_available.rb new file mode 100755 index 00000000..44f08c08 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_function_available.rb @@ -0,0 +1,9 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_hash_spec.rb new file mode 100755 index 00000000..c2599a02 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_hash_spec.rb @@ -0,0 +1,11 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_integer_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_integer_spec.rb new file mode 100755 index 00000000..b296830e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_integer_spec.rb @@ -0,0 +1,45 @@ +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) } + + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(50).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(50).and_return(true) + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ip_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ip_address_spec.rb new file mode 100755 index 00000000..39525d7a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ip_address_spec.rb @@ -0,0 +1,40 @@ +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) } + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.2.3.4').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4').and_return(true) + end + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv4_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv4_address_spec.rb new file mode 100644 index 00000000..985260cd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv4_address_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'is_ipv4_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) } + + SharedData::IPV4_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first).and_return(true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv6_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv6_address_spec.rb new file mode 100644 index 00000000..acd6a87f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_ipv6_address_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe 'is_ipv6_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('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) } + it { is_expected.to run.with_params('85a3:0000:0000:8a2e:0370:7334:100.100.100.100').and_return(true) } + 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('').and_return(false) } + it { is_expected.to run.with_params('one').and_return(false) } + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_mac_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_mac_address_spec.rb new file mode 100755 index 00000000..5f76a91b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_mac_address_spec.rb @@ -0,0 +1,24 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_numeric_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_numeric_spec.rb new file mode 100755 index 00000000..5962d8a1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_numeric_spec.rb @@ -0,0 +1,48 @@ +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) } + + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(7).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(7).and_return(true) + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_string_spec.rb new file mode 100755 index 00000000..e92f85cc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/is_string_spec.rb @@ -0,0 +1,47 @@ +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) } + + context 'Checking for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('sponge').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('bob').and_return(true) + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_keys_to_values_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_keys_to_values_spec.rb new file mode 100755 index 00000000..c2bae5b0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_keys_to_values_spec.rb @@ -0,0 +1,23 @@ +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.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) + end + it 'should run join_keys_to_values(, " ") and return the proper array' do + result = subject.call([{ 'key1' => 'value1', 'key2' => ['value2', 'value3'] }, ' ']) + expect(result.sort).to eq(['key1 value1', 'key2 value2', 'key2 value3'].sort) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_spec.rb new file mode 100755 index 00000000..a3005714 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/join_spec.rb @@ -0,0 +1,19 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/keys_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/keys_spec.rb new file mode 100755 index 00000000..2e009dcc --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/keys_spec.rb @@ -0,0 +1,19 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/load_module_metadata_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/load_module_metadata_spec.rb new file mode 100755 index 00000000..1a61e2c9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/load_module_metadata_spec.rb @@ -0,0 +1,38 @@ +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) } + + describe "when calling with valid arguments" do + before :each do + if RSpec.configuration.puppet_future + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/, {:encoding=>"utf-8"}).and_return('{"name": "puppetlabs-stdlib"}') + else + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/).and_return('{"name": "puppetlabs-stdlib"}') + end + end + 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('/path/to/module/metadata.json').and_return(true) + allow(File).to receive(:read).with('/path/to/module/metadata.json').and_return('{"name": "spencer-science"}') + + result = subject.call(['science']) + expect(result['name']).to eq('spencer-science') + 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('/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('/path/to/module/metadata.json').and_return(false) + result = subject.call(['science', true]) + expect(result).to eq({}) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadjson_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadjson_spec.rb new file mode 100644 index 00000000..a00dff93 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadjson_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +describe 'loadjson' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + + describe "when calling with valid arguments" do + before :each do + if RSpec.configuration.puppet_future + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/, {:encoding=>"utf-8"}).and_return('{"name": "puppetlabs-stdlib"}') + else + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/).and_return('{"name": "puppetlabs-stdlib"}') + end + end + + context 'when a non-existing file is specified' do + let(:filename) { '/tmp/doesnotexist' } + before { + allow(File).to receive(:exists?).with(filename).and_return(false).once + allow(PSON).to receive(:load).never + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end + + context 'when an existing file is specified' do + let(:filename) { '/tmp/doesexist' } + let(:data) { { 'key' => 'value' } } + let(:json) { '{"key":"value"}' } + before { + allow(File).to receive(:exists?).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 + allow(PSON).to receive(:load).with(json).and_return(data).once + } + it { is_expected.to run.with_params(filename).and_return(data) } + end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + let(:json) { '{"key":"value"}' } + before { + allow(File).to receive(:exists?).with(filename).and_return(true).once + allow(File).to receive(:read).with(filename).and_return(json).once + allow(PSON).to receive(:load).with(json).once.and_raise StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadyaml_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadyaml_spec.rb new file mode 100755 index 00000000..9f16a1a5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/loadyaml_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe 'loadyaml' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /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, {'default' => 'value'}).and_return({'default' => 'value'}) } + 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 + } + it { is_expected.to run.with_params(filename).and_return(data) } + end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + before { + File.expects(:exists?).with(filename).returns(true).once + YAML.stubs(:load_file).with(filename).once.raises StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/lstrip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/lstrip_spec.rb new file mode 100755 index 00000000..981794ed --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/lstrip_spec.rb @@ -0,0 +1,34 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/max_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/max_spec.rb new file mode 100755 index 00000000..66fb0c86 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/max_spec.rb @@ -0,0 +1,21 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/member_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/member_spec.rb new file mode 100755 index 00000000..527f887f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/member_spec.rb @@ -0,0 +1,21 @@ +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 { + 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(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([''], ['']).and_return(true) } + it { is_expected.to run.with_params([], 'one').and_return(false) } + it { is_expected.to run.with_params([], ['one']).and_return(false) } + 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(['one', 'two', 'three', 'four'], ['four', 'five']).and_return(false) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/merge_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/merge_spec.rb new file mode 100755 index 00000000..7b53363e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/merge_spec.rb @@ -0,0 +1,25 @@ +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/) } + it { + pending 'should not special case this' + 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({ 'key1' => 'value1' }, { 'key2' => 'value2' }, { 'key3' => 'value3' }) \ + .and_return({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }) + } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/min_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/min_spec.rb new file mode 100755 index 00000000..c840a72c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/min_spec.rb @@ -0,0 +1,21 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/num2bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/num2bool_spec.rb new file mode 100755 index 00000000..494afff9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/num2bool_spec.rb @@ -0,0 +1,22 @@ +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.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) } + it { is_expected.to run.with_params('1.5').and_return(true) } + it { is_expected.to run.with_params(-1).and_return(false) } + it { is_expected.to run.with_params('-1').and_return(false) } + it { is_expected.to run.with_params(-1.5).and_return(false) } + it { is_expected.to run.with_params('-1.5').and_return(false) } + 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_return(false) } + it { is_expected.to run.with_params('{}').and_raise_error(Puppet::ParseError, /does not look like a number/) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/parsejson_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/parsejson_spec.rb new file mode 100755 index 00000000..a01f1f67 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/parsejson_spec.rb @@ -0,0 +1,64 @@ +require 'spec_helper' + +describe 'parsejson' do + it 'should exist' do + is_expected.not_to eq(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) + end + + context 'with correct JSON data' do + + 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'}) + 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']) + 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({}) + 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] } }) + 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'}) + 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) + end + + it 'should support a structure for a default value' do + is_expected.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') + end + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/parseyaml_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/parseyaml_spec.rb new file mode 100755 index 00000000..fa947ca6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/parseyaml_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' + +describe 'parseyaml' do + it 'should exist' do + is_expected.not_to eq(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) + 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') + 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'}) + 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']) + 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]}}) + 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'}) + 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) + 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 + + 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'}) + 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') + end + end + + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' 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') + end + end + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_default_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_default_spec.rb new file mode 100755 index 00000000..e2fc64a1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_default_spec.rb @@ -0,0 +1,24 @@ +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.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') } + + [ '', :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, 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) } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_spec.rb new file mode 100755 index 00000000..2c7caa87 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pick_spec.rb @@ -0,0 +1,12 @@ +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.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') } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/prefix_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/prefix_spec.rb new file mode 100755 index 00000000..37610221 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/prefix_spec.rb @@ -0,0 +1,28 @@ +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 { + 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) + } + 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_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'], '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({}, '').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({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ + .and_return({ 'prekey1' => 'value1', 'prekey2' => 'value2', 'prekey3' => 'value3' }) + } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/private_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/private_spec.rb new file mode 100644 index 00000000..a13be643 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/private_spec.rb @@ -0,0 +1,56 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/pw_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pw_hash_spec.rb new file mode 100644 index 00000000..df5348c9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/pw_hash_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe 'pw_hash' do + + it { is_expected.not_to eq(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) } + 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) } + 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/) } + end + + context 'when the first argument is undefined' do + it { is_expected.to run.with_params('', 'sha-256', 'salt').and_return(nil) } + it { is_expected.to run.with_params(nil, 'sha-256', 'salt').and_return(nil) } + 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/) } + 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/) } + 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/) } + 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/) } + 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/) } + 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') } + + it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_raise_error(Puppet::ParseError, /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 + 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/range_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/range_spec.rb new file mode 100755 index 00000000..492cad40 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/range_spec.rb @@ -0,0 +1,118 @@ +require 'spec_helper' + +describe 'range' 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 third.") + is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /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) } + 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) } + end + + context 'with characters as bounds' do + it { is_expected.to run.with_params('d', 'a').and_return([]) } + it { is_expected.to run.with_params('a', 'a').and_return(['a']) } + it { is_expected.to run.with_params('a', 'b').and_return(['a', 'b']) } + it { is_expected.to run.with_params('a', 'd').and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', 1).and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', '1').and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', 2).and_return(['a', 'c']) } + it { is_expected.to run.with_params('a', 'd', -2).and_return(['a', 'c']) } + it { is_expected.to run.with_params('a', 'd', 3).and_return(['a', 'd']) } + it { is_expected.to run.with_params('a', 'd', 4).and_return(['a']) } + end + + context 'with strings as bounds' do + it { is_expected.to run.with_params('onea', 'oned').and_return(['onea', 'oneb', 'onec', 'oned']) } + it { is_expected.to run.with_params('two', 'one').and_return([]) } + it { is_expected.to run.with_params('true', 'false').and_return([]) } + it { is_expected.to run.with_params('false', 'true').and_return(['false']) } + end + + context 'with integers as bounds' do + it { is_expected.to run.with_params(4, 1).and_return([]) } + it { is_expected.to run.with_params(1, 1).and_return([1]) } + it { is_expected.to run.with_params(1, 2).and_return([1, 2]) } + it { is_expected.to run.with_params(1, 4).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, 1).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, '1').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, 2).and_return([1, 3]) } + it { is_expected.to run.with_params(1, 4, -2).and_return([1, 3]) } + it { is_expected.to run.with_params(1, 4, 3).and_return([1, 4]) } + it { is_expected.to run.with_params(1, 4, 4).and_return([1]) } + end + + context 'with integers as strings as bounds' do + it { is_expected.to run.with_params('4', '1').and_return([]) } + it { is_expected.to run.with_params('1', '1').and_return([1]) } + it { is_expected.to run.with_params('1', '2').and_return([1, 2]) } + it { is_expected.to run.with_params('1', '4').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', 1).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', '1').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', 2).and_return([1, 3]) } + it { is_expected.to run.with_params('1', '4', -2).and_return([1, 3]) } + it { is_expected.to run.with_params('1', '4', 3).and_return([1, 4]) } + it { is_expected.to run.with_params('1', '4', 4).and_return([1]) } + end + + context 'with prefixed numbers as strings as bounds' do + it { is_expected.to run.with_params('host01', 'host04').and_return(['host01', 'host02', 'host03', 'host04']) } + it { is_expected.to run.with_params('01', '04').and_return([1, 2, 3, 4]) } + 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]) } + it { is_expected.to run.with_params('1-2').and_return([1, 2]) } + it { is_expected.to run.with_params('1-4').and_return([1, 2, 3, 4]) } + end + + context 'with two-dot-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]) } + it { is_expected.to run.with_params('1..2').and_return([1, 2]) } + it { is_expected.to run.with_params('1..4').and_return([1, 2, 3, 4]) } + end + + context 'with three-dot-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([]) } + it { is_expected.to run.with_params('1...2').and_return([1]) } + it { is_expected.to run.with_params('1...3').and_return([1, 2]) } + it { is_expected.to run.with_params('1...5').and_return([1, 2, 3, 4]) } + end + + 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/) + } + 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/) + } + 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/) + } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/regexpescape_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/regexpescape_spec.rb new file mode 100644 index 00000000..6efa8473 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/regexpescape_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe 'regexpescape' 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 + + describe 'handling normal strings' do + it 'should call ruby\'s Regexp.escape function' do + Regexp.expects(:escape).with('regexp_string').returns('escaped_regexp_string').once + is_expected.to run.with_params('regexp_string').and_return('escaped_regexp_string') + end + end + + describe 'handling classes derived from String' do + it 'should call ruby\'s Regexp.escape function' do + regexp_string = AlsoString.new('regexp_string') + Regexp.expects(:escape).with(regexp_string).returns('escaped_regexp_string').once + is_expected.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"]) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/reject_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/reject_spec.rb new file mode 100755 index 00000000..48630507 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/reject_spec.rb @@ -0,0 +1,19 @@ +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 { + 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/) + } + 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/) + } + 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']) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/reverse_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/reverse_spec.rb new file mode 100755 index 00000000..e00dee92 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/reverse_spec.rb @@ -0,0 +1,31 @@ +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 { + 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, /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([]).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('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') } + + context 'when using a class extending String' do + it 'should call its reverse method' do + value = AlsoString.new('asdfghjkl') + value.expects(:reverse).returns('foo') + expect(subject).to run.with_params(value).and_return('foo') + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/rstrip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/rstrip_spec.rb new file mode 100755 index 00000000..d2efac8e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/rstrip_spec.rb @@ -0,0 +1,34 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/seeded_rand_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/seeded_rand_spec.rb new file mode 100644 index 00000000..38e134eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/seeded_rand_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe 'seeded_rand' do + 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(1).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 a string/) } + it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, /second argument must be a string/) } + + it "provides a random number strictly less than the given max" do + expect(seeded_rand(3, 'seed')).to satisfy {|n| n.to_i < 3 } + end + + it "provides a random number greater or equal to zero" do + expect(seeded_rand(3, 'seed')).to satisfy {|n| n.to_i >= 0 } + end + + it "provides the same 'random' value on subsequent calls for the same host" do + expect(seeded_rand(10, 'seed')).to eql(seeded_rand(10, 'seed')) + end + + it "allows seed to control the random value on a single host" do + first_random = seeded_rand(1000, 'seed1') + second_different_random = seeded_rand(1000, 'seed2') + + expect(first_random).not_to eql(second_different_random) + end + + it "should not return different values for different hosts" do + val1 = seeded_rand(1000, 'foo', :host => "first.host.com") + val2 = seeded_rand(1000, 'foo', :host => "second.host.com") + + expect(val1).to eql(val2) + end + + def seeded_rand(max, seed, args = {}) + host = args[:host] || '127.0.0.1' + + # 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) + + scope.function_seeded_rand([max, seed]) + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_escape_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_escape_spec.rb new file mode 100644 index 00000000..3061decd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_escape_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'shell_escape' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' 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('foo', 'bar').and_raise_error(Puppet::ParseError, /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 '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 { is_expected.to run.with_params('~`!@#$%^&*()_+-=[]\{}|;\':",./<>?') + .and_return('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_join_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_join_spec.rb new file mode 100644 index 00000000..6815f7c1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_join_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'shell_join' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' 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(['foo'], ['bar']).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo').and_raise_error(Puppet::ParseError, /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 { is_expected.to run.with_params(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) + .and_return('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') } + end + + describe 'stringification' do + it { is_expected.to run.with_params([10, false, 'foo']).and_return('10 false foo') } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_split_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_split_spec.rb new file mode 100644 index 00000000..beeb9774 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shell_split_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'shell_split' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' 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('foo', 'bar').and_raise_error(Puppet::ParseError, /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 { is_expected.to run.with_params('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') + .and_return(['~`!@#$%^&*()_+-=[]\{}|;\':",./<>?']) } + it { is_expected.to run.with_params('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') + .and_return(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/shuffle_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shuffle_spec.rb new file mode 100755 index 00000000..ebc3a732 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/shuffle_spec.rb @@ -0,0 +1,33 @@ +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 { + 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, /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/) } + + context 'when running with a specific seed' do + # make tests deterministic + before(:each) { srand(2) } + + 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') } + + context 'when using a class extending String' do + it { is_expected.to run.with_params(AlsoString.new('asdfghjkl')).and_return('lkhdsfajg') } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/size_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/size_spec.rb new file mode 100755 index 00000000..c0047ee2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/size_spec.rb @@ -0,0 +1,35 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/sort_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/sort_spec.rb new file mode 100755 index 00000000..9abd039c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/sort_spec.rb @@ -0,0 +1,24 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/squeeze_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/squeeze_spec.rb new file mode 100755 index 00000000..7f09c30f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/squeeze_spec.rb @@ -0,0 +1,44 @@ +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.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) } + + context 'when squeezing a single 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('aaaaaaaaa').and_return('a') } + it { is_expected.to run.with_params('aaaaaaaaa', 'a').and_return('a') } + it { is_expected.to run.with_params('aaaaaaaaabbbbbbbbbbcccccccccc', 'b-c').and_return('aaaaaaaaabc') } + end + + context 'when squeezing values in an array' do + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc']) \ + .and_return( ['', 'a', 'a', 'abc']) + } + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'a') \ + .and_return( ['', 'a', 'a', 'abbbbbbbbbbcccccccccc']) + } + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'b-c') \ + .and_return( ['', 'a', 'aaaaaaaaa', 'aaaaaaaaabc']) + } + end + + context 'when using a class extending String' do + it 'should call its squeeze method' do + value = AlsoString.new('aaaaaaaaa') + value.expects(:squeeze).returns('foo') + expect(subject).to run.with_params(value).and_return('foo') + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2bool_spec.rb new file mode 100755 index 00000000..7d8c47c1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2bool_spec.rb @@ -0,0 +1,23 @@ +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 { + 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) + } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Unknown type of boolean given/) } + + describe 'when testing values that mean "true"' do + [ '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| + it { is_expected.to run.with_params(value).and_return(false) } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2saltedsha512_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2saltedsha512_spec.rb new file mode 100755 index 00000000..2e1e818b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/str2saltedsha512_spec.rb @@ -0,0 +1,17 @@ +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/) } + + 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') } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/strftime_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/strftime_spec.rb new file mode 100755 index 00000000..e76774aa --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/strftime_spec.rb @@ -0,0 +1,26 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/strip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/strip_spec.rb new file mode 100755 index 00000000..689b6dd0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/strip_spec.rb @@ -0,0 +1,34 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/suffix_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/suffix_spec.rb new file mode 100755 index 00000000..efba4ab4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/suffix_spec.rb @@ -0,0 +1,38 @@ +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 { + 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) + } + 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_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({ '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 { + is_expected.to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'post') \ + .and_return({ 'key1post' => 'value1', 'key2post' => 'value2', 'key3post' => 'value3' }) + } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/swapcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/swapcase_spec.rb new file mode 100755 index 00000000..c175a158 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/swapcase_spec.rb @@ -0,0 +1,40 @@ +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 { + 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) + } + 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/) } + 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']) } + 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', 'ONE']).and_return(['ONE', 'one']) } + 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]) } + it { is_expected.to run.with_params(['OnE', []]).and_return(['oNe', []]) } + 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') + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/time_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/time_spec.rb new file mode 100755 index 00000000..d157939e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/time_spec.rb @@ -0,0 +1,21 @@ +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) } + + context 'when running at a specific time' do + before(:each) { + # 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) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/to_bytes_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/to_bytes_spec.rb new file mode 100755 index 00000000..2be23ff2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/to_bytes_spec.rb @@ -0,0 +1,72 @@ +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/) } + + describe 'when passing numbers' do + it { is_expected.to run.with_params(0).and_return(0) } + it { is_expected.to run.with_params(1).and_return(1) } + it { is_expected.to run.with_params(-1).and_return(-1) } + it { is_expected.to run.with_params(1.1).and_return(1.1) } + it { is_expected.to run.with_params(-1.1).and_return(-1.1) } + end + + describe 'when passing numbers as strings' do + describe 'without a unit' do + it { is_expected.to run.with_params('1').and_return(1) } + it { is_expected.to run.with_params('-1').and_return(-1) } + # these are so wrong + it { is_expected.to run.with_params('1.1').and_return(1) } + it { is_expected.to run.with_params('-1.1').and_return(-1) } + end + + 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('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) } + + # these are so wrong + it { is_expected.to run.with_params('1.0001 k').and_return(1024) } + it { is_expected.to run.with_params('-1.0001 kB').and_return(-1024) } + 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/) } + end + end + + # these are so wrong + describe 'when passing random stuff' do + it { is_expected.to run.with_params('-1....1').and_return(-1) } + it { is_expected.to run.with_params('-1.e.e.e.1').and_return(-1) } + it { is_expected.to run.with_params('-1+1').and_return(-1) } + it { is_expected.to run.with_params('1-1').and_return(1) } + it { is_expected.to run.with_params('1 kaboom').and_return(1024) } + it { is_expected.to run.with_params('kaboom').and_return(0) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/try_get_value_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/try_get_value_spec.rb new file mode 100644 index 00000000..38c0efdd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/try_get_value_spec.rb @@ -0,0 +1,100 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/type3x_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type3x_spec.rb new file mode 100644 index 00000000..c3eb1dee --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type3x_spec.rb @@ -0,0 +1,41 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_of_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_of_spec.rb new file mode 100644 index 00000000..cc9ef781 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_of_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +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) } + 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) } + 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) + end + + it 'gives the type of an integer' do + expect(subject.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_spec.rb new file mode 100755 index 00000000..4288df09 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/type_spec.rb @@ -0,0 +1,42 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/union_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/union_spec.rb new file mode 100755 index 00000000..cfd38b60 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/union_spec.rb @@ -0,0 +1,24 @@ +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/) } + end + + 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'], ['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', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } + 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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/unique_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/unique_spec.rb new file mode 100755 index 00000000..24257a01 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/unique_spec.rb @@ -0,0 +1,27 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/unix2dos_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/unix2dos_spec.rb new file mode 100644 index 00000000..8537a26f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/unix2dos_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'unix2dos' do + context 'Checking parameter validity' do + it { is_expected.not_to eq(nil) } + it do + is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + end + end + + context '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) + end + end + + context '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) + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/upcase_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/upcase_spec.rb new file mode 100755 index 00000000..3b7b02d4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/upcase_spec.rb @@ -0,0 +1,26 @@ +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/tools/laptop_puppetisation/modules/stdlib/spec/functions/uriescape_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/uriescape_spec.rb new file mode 100755 index 00000000..f05ec088 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/uriescape_spec.rb @@ -0,0 +1,36 @@ +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 + + 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') + 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") + 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 +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_absolute_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_absolute_path_spec.rb new file mode 100755 index 00000000..9397da5c --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_absolute_path_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe 'validate_absolute_path' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('c:/') + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_array_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_array_spec.rb new file mode 100755 index 00000000..409b3dc7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_array_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'validate_array' do + + describe 'signature validation' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + it { is_expected.not_to eq(nil) } + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params([]) + end + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_augeas_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_augeas_spec.rb new file mode 100755 index 00000000..4236649d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_augeas_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +describe 'validate_augeas' do + unless Puppet.features.augeas? + skip "ruby-augeas not installed" + else + 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.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'], + ] + + inputs.each do |input| + it { is_expected.to run.with_params(*input) } + end + end + + describe 'valid inputs which fail augeas validation' do + # The intent here is to make sure valid inputs raise exceptions when they + # 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' ], + ] + + inputs.each do |input| + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /validate_augeas.*?matched less than it should/) } + end + end + + 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' ], + ] + + inputs.each do |input| + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /#{input[3]}/) } + end + end + + 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']], + ] + + inputs.each do |input| + it { is_expected.to run.with_params(*input) } + end + end + + 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']], + ] + + inputs.each do |input| + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /testing path/) } + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_bool_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_bool_spec.rb new file mode 100755 index 00000000..3074d885 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_bool_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe 'validate_bool' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(true) + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_cmd_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_cmd_spec.rb new file mode 100755 index 00000000..ab0cbc9a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_cmd_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe 'validate_cmd' do + let(:touch) { File.exists?('/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 { + pending('should implement stricter type checking') + is_expected.to run.with_params([], '', '').and_raise_error(Puppet::ParseError, /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/) + } + 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/) + } + 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/) } + 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/) } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_email_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_email_address_spec.rb new file mode 100644 index 00000000..76283834 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_email_address_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'validate_email_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('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(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 email/) } + it { is_expected.to run.with_params('bob@gmail.com', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', 'one').and_raise_error(Puppet::ParseError, /is not a valid email/) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_hash_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_hash_spec.rb new file mode 100755 index 00000000..7533abe1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_hash_spec.rb @@ -0,0 +1,38 @@ +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 'check for deprecation warning' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params({'key' => 'value'}) + end + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_integer_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_integer_spec.rb new file mode 100755 index 00000000..6558d00f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_integer_spec.rb @@ -0,0 +1,101 @@ +require 'spec_helper' + +describe 'validate_integer' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ip_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ip_address_spec.rb new file mode 100644 index 00000000..0414f5e5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ip_address_spec.rb @@ -0,0 +1,65 @@ +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 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.2.3.4') + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4') + end + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv4_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv4_address_spec.rb new file mode 100755 index 00000000..6e4ca054 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv4_address_spec.rb @@ -0,0 +1,41 @@ +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) } + end + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first) + end + end + + SharedData::IPV4_PATTERNS.each do |value| + it { is_expected.to run.with_params(value) } + end + + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + end + + describe 'invalid inputs' do + [ {}, [], 1, true ].each do |invalid| + it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first, invalid).and_raise_error(Puppet::ParseError, /is not a string/) } + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv6_address_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv6_address_spec.rb new file mode 100755 index 00000000..78810d43 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_ipv6_address_spec.rb @@ -0,0 +1,50 @@ +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) } + end + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('3ffe:0505:0002::') + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('3ffe:0505:0002::') + end + end + + 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 diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_legacy_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_legacy_spec.rb new file mode 100644 index 00000000..50cb317d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_legacy_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'validate_legacy' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + + describe 'when passing the type assertion and passing the previous validation' do + before do + scope.expects(:function_validate_foo).with([5]).once + Puppet.expects(:notice).never + end + it 'passes without notice' do + is_expected.to run.with_params('Integer', 'validate_foo', 5) + end + end + + describe 'when passing the type assertion and failing the previous validation' do + before do + scope.expects(:function_validate_foo).with([5]).raises(Puppet::ParseError, 'foo').once + Puppet.expects(:notice).with(includes('Accepting previously invalid value for target type')) + end + it 'passes with a notice about newly accepted value' do + is_expected.to run.with_params('Integer', 'validate_foo', 5) + end + end + + describe 'when failing the type assertion and passing the previous validation' do + before do + scope.expects(:function_validate_foo).with(['5']).once + subject.func.expects(:call_function).with('deprecation', 'validate_legacy', includes('Integer')).once + end + it 'passes with a deprecation message' do + is_expected.to run.with_params('Integer', 'validate_foo', '5') + end + end + + describe 'when failing the type assertion and failing the previous validation' do + before do + scope.expects(:function_validate_foo).with(['5']).raises(Puppet::ParseError, 'foo').once + subject.func.expects(:call_function).with('fail', includes('Integer')).once + end + it 'fails with a helpful message' do + is_expected.to run.with_params('Integer', 'validate_foo', '5') + end + end + + describe 'when passing in undef' do + before do + scope.expects(:function_validate_foo).with([:undef]).once + Puppet.expects(:notice).never + end + it 'works' do + is_expected.to run.with_params('Optional[Integer]', 'validate_foo', :undef) + end + end + + describe 'when passing in multiple arguments' do + before do + scope.expects(:function_validate_foo).with([:undef, 1, 'foo']).once + Puppet.expects(:notice).never + end + it 'passes with a deprecation message' do + is_expected.to run.with_params('Optional[Integer]', 'validate_foo', :undef, 1, 'foo') + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_numeric_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_numeric_spec.rb new file mode 100755 index 00000000..4c0e24dd --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_numeric_spec.rb @@ -0,0 +1,100 @@ +require 'spec_helper' + +describe 'validate_numeric' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_re_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_re_spec.rb new file mode 100755 index 00000000..35311829 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_re_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' + +describe 'validate_re' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('', '') + end + + 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 { 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_slength_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_slength_spec.rb new file mode 100755 index 00000000..e4162dee --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_slength_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe 'validate_slength' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1234567890', 10) + end + + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_string_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_string_spec.rb new file mode 100755 index 00000000..0907ede9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_string_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe 'validate_string' do + after(:all) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('', '') + end + + 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(nil) } + 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/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_x509_rsa_key_pair_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_x509_rsa_key_pair_spec.rb new file mode 100755 index 00000000..eb633100 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/validate_x509_rsa_key_pair_spec.rb @@ -0,0 +1,180 @@ +require 'spec_helper' + +describe 'validate_x509_rsa_key_pair' do + + let(:valid_cert) do + < '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/tools/laptop_puppetisation/modules/stdlib/spec/functions/zip_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/functions/zip_spec.rb new file mode 100755 index 00000000..abca7ee8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/functions/zip_spec.rb @@ -0,0 +1,15 @@ +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 { + 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) + } + 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]) } +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/alias_should_to_must.rb b/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/alias_should_to_must.rb new file mode 100755 index 00000000..505e2409 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/alias_should_to_must.rb @@ -0,0 +1,9 @@ +#! /usr/bin/env ruby -S rspec +require 'rspec' + +class Object + # This is necessary because the RAL has a 'should' + # method. + alias :must :should + alias :must_not :should_not +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/publicize_methods.rb b/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/publicize_methods.rb new file mode 100755 index 00000000..3ae59f97 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/monkey_patches/publicize_methods.rb @@ -0,0 +1,11 @@ +#! /usr/bin/env ruby -S rspec +# 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 + + self.class_eval { public(*saved_private_instance_methods) } + yield + self.class_eval { private(*saved_private_instance_methods) } + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper.rb b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper.rb new file mode 100755 index 00000000..22d5d689 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper.rb @@ -0,0 +1,8 @@ +#This file is generated by ModuleSync, do not edit. +require 'puppetlabs_spec_helper/module_spec_helper' + +# put local configuration and setup into spec_helper_local +begin + require 'spec_helper_local' +rescue LoadError +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_acceptance.rb b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_acceptance.rb new file mode 100755 index 00000000..8a1907f8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_acceptance.rb @@ -0,0 +1,70 @@ +#! /usr/bin/env ruby -S rspec +require 'beaker-rspec' +require 'beaker/puppet_install_helper' + +UNSUPPORTED_PLATFORMS = [] + +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' || ENV['PUPPET_INSTALL_TYPE'] == 'agent' + 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 diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_local.rb b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_local.rb new file mode 100644 index 00000000..616490c6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/spec_helper_local.rb @@ -0,0 +1,31 @@ +# 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/tools/laptop_puppetisation/modules/stdlib/spec/support/shared_data.rb b/tools/laptop_puppetisation/modules/stdlib/spec/support/shared_data.rb new file mode 100644 index 00000000..ea9b7a0a --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/support/shared_data.rb @@ -0,0 +1,38 @@ +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', + ] + 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', + ] +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb new file mode 100755 index 00000000..0afadb25 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb @@ -0,0 +1,32 @@ +#! /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/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/package_provider_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/package_provider_spec.rb new file mode 100644 index 00000000..3954faf0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/package_provider_spec.rb @@ -0,0 +1,44 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/package' + +describe 'package_provider', :type => :fact do + before { Facter.clear } + after { Facter.clear } + + ['4.2.2', '3.7.1 (Puppet Enterprise 3.2.1)'].each do |puppetversion| + describe "on puppet ''#{puppetversion}''" do + before :each do + Facter.stubs(:value).returns puppetversion + end + + 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') + end + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/pe_version_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/pe_version_spec.rb new file mode 100755 index 00000000..c11a1cd0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/pe_version_spec.rb @@ -0,0 +1,88 @@ +#!/usr/bin/env rspec + +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 + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(nil) + end + + it "pe_version is nil" do + expect(Facter.fact(:puppetversion).value).to be_nil + 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| + puppetversion = "2.7.19 (Puppet Enterprise #{version})" + context "puppetversion => #{puppetversion}" do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(puppetversion) + end + + (major,minor,patch) = version.split(".") + + it "Should return true" do + expect(Facter.fact(:is_pe).value).to eq(true) + end + + it "Should have a version of #{version}" do + expect(Facter.fact(:pe_version).value).to eq(version) + end + + it "Should have 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 + expect(Facter.fact(:pe_minor_version).value).to eq(minor) + end + + it "Should have 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 + before :each do + Facter.fact(:puppetversion).stubs(:value).returns("2.7.19") + end + + it "is_pe is false" do + expect(Facter.fact(:is_pe).value).to eq(false) + end + + it "pe_version is nil" do + expect(Facter.fact(:pe_version).value).to be_nil + end + + 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 + expect(Facter.fact(:pe_minor_version).value).to be_nil + end + + it "Should have a patch version" do + expect(Facter.fact(:pe_patch_version).value).to be_nil + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/root_home_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/root_home_spec.rb new file mode 100755 index 00000000..a5c2846e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/root_home_spec.rb @@ -0,0 +1,65 @@ +#! /usr/bin/env ruby -S rspec +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 } + + 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')) + + 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 + 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')) + + 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/service_provider_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/service_provider_spec.rb new file mode 100644 index 00000000..ad8a5fc5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/service_provider_spec.rb @@ -0,0 +1,37 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/service' + +describe 'service_provider', :type => :fact do + before { Facter.clear } + after { Facter.clear } + + context "macosx" do + it "should return launchd" do + provider = Puppet::Type.type(:service).provider(:launchd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('launchd') + end + end + + context "systemd" do + it "should return systemd" do + provider = Puppet::Type.type(:service).provider(:systemd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('systemd') + end + end + + context "redhat" do + it "should return redhat" do + provider = Puppet::Type.type(:service).provider(:redhat) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('redhat') + end + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb new file mode 100755 index 00000000..c278b798 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb @@ -0,0 +1,37 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'facter/util/puppet_settings' + +describe Facter::Util::PuppetSettings do + + describe "#with_puppet" do + context "Without Puppet loaded" do + before(:each) do + Module.expects(:const_get).with("Puppet").raises(NameError) + end + + it 'should be nil' do + expect(subject.with_puppet { Puppet[:vardir] }).to be_nil + end + it 'should not yield to the block' do + Puppet.expects(:[]).never + expect(subject.with_puppet { Puppet[:vardir] }).to be_nil + end + end + context "With Puppet loaded" do + module Puppet; end + let(:vardir) { "/var/lib/puppet" } + + before :each do + Puppet.expects(:[]).with(:vardir).returns vardir + end + + it 'should yield to the block' do + subject.with_puppet { Puppet[:vardir] } + end + it 'should return the nodes vardir' do + expect(subject.with_puppet { Puppet[:vardir] }).to eq vardir + end + end + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb new file mode 100644 index 00000000..b162127d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb @@ -0,0 +1,69 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the enclose_ipv6 function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("enclose_ipv6")).to eq("function_enclose_ipv6") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_enclose_ipv6([]) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError if there is more than 1 arguments" do + expect { scope.function_enclose_ipv6(['argument1','argument2']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given garbage" do + expect { scope.function_enclose_ipv6(['garbage']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise 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 "should not raise a ParseError when given a single ip string" do + expect { scope.function_enclose_ipv6(['127.0.0.1']) }.to_not raise_error + end + + it "should not raise a ParseError when given * as ip string" do + expect { scope.function_enclose_ipv6(['*']) }.to_not raise_error + end + + it "should not raise a ParseError when given an array of ip strings" do + expect { scope.function_enclose_ipv6([['127.0.0.1','fe80::1']]) }.to_not raise_error + end + + it "should 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]']]) }.to_not raise_error + end + + it "should raise 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 "should raise 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 "should raise a ParseError when given a wrong ipv6 address" do + expect { scope.function_enclose_ipv6(['fe80:::1']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should embrace 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 "should embrace a single ipv6 adresse" do + result = scope.function_enclose_ipv6(['fe80::1']) + expect(result).to(eq(['[fe80::1]'])) + end + + it "should 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/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb new file mode 100644 index 00000000..89312081 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb @@ -0,0 +1,86 @@ +require 'spec_helper' + +describe :is_absolute_path do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + let(:function_args) do + [] + end + + let(:function) do + scope.function_is_absolute_path(function_args) + end + + + describe 'validate arity' do + let(:function_args) do + [1,2] + end + it "should raise a ParseError if there is more than 1 arguments" do + lambda { function }.should( raise_error(ArgumentError)) + end + + end + + it "should exist" do + Puppet::Parser::Functions.function(subject).should == "function_#{subject}" + end + + # help enforce good function defination + it 'should contain arity' do + + end + + it "should raise a ParseError if there is less than 1 arguments" do + lambda { function }.should( raise_error(ArgumentError)) + end + + + describe 'should retrun true' do + let(:return_value) do + true + end + + describe 'windows' do + let(:function_args) do + ['c:\temp\test.txt'] + end + it 'should return data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['/temp/test.txt'] + end + + it 'should return data' do + function.should eq(return_value) + end + end + end + + describe 'should return false' do + let(:return_value) do + false + end + describe 'windows' do + let(:function_args) do + ['..\temp\test.txt'] + end + it 'should return data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['../var/lib/puppet'] + end + it 'should return data' do + function.should eq(return_value) + end + end + end +end \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb new file mode 100755 index 00000000..1f41f625 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -0,0 +1,447 @@ +#! /usr/bin/env ruby -S rspec +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 + + 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 + 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 + + it 'should not replace the matching line' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo=blah\nfoo2\nfoo3") + 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") + 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\./) + 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 + + 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 + + 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\./) + 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") + end + end + + describe 'using 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 '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 '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 '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 + 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 + 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) + end + it 'should remove the line if it exists' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + 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") + 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") + 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( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :match_for_absence => true, + } + ) + @provider = provider_class.new(@resource) + end + + it 'should find a line to match' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + expect(@provider.exists?).to be_truthy + end + + it 'should remove one line if it matches' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + 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") + 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( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :multiple => true, + :match_for_absence => 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") + end + + it 'should ignore 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.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + end + + it 'should ignore 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.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb new file mode 100755 index 00000000..c738a272 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby + +require 'spec_helper' + +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]") + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb new file mode 100755 index 00000000..48e2670f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb @@ -0,0 +1,76 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'tempfile' +describe Puppet::Type.type(:file_line) do + let :file_line do + Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'line', :path => '/tmp/path') + end + it 'should accept a line and path' 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 + 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 + expect { + Puppet::Type.type(:file_line).new( + :name => 'foo', + :path => '/my/path', + :line => 'foo=bar', + :match => '^bar=blah$' + )}.not_to raise_error + end + it 'should accept 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 'should accept 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/) + 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, /line is a required attribute/) + end + it 'should not require that a line is specified when matching for absence' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file', :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error + 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, /path is a required attribute/) + end + it 'should default to ensure => present' do + expect(file_line[:ensure]).to eq :present + end + it 'should default to replace => true' do + expect(file_line[:replace]).to eq :true + end + + it "should autorequire the file it manages" do + catalog = Puppet::Resource::Catalog.new + 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) + end + expect(relationship).to be_a Puppet::Relationship + end + + it "should 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 + end +end diff --git a/tools/laptop_puppetisation/modules/stdlib/types/absolutepath.pp b/tools/laptop_puppetisation/modules/stdlib/types/absolutepath.pp new file mode 100644 index 00000000..70ec9164 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/absolutepath.pp @@ -0,0 +1,2 @@ +# A strict absolutepath type +type Stdlib::Absolutepath = Variant[Stdlib::Windowspath, Stdlib::Unixpath] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/absolute_path.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/absolute_path.pp new file mode 100644 index 00000000..d11784e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/absolute_path.pp @@ -0,0 +1,7 @@ +# Emulate the is_absolute_path and validate_absolute_path functions +# +# The first pattern is originally from is_absolute_path, which had it from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? +# slash = '[\\\\/]' +# name = '[^\\\\/]+' +# %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, +type Stdlib::Compat::Absolute_path = Variant[Pattern[/^(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+))/], Pattern[/^\//]] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/array.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/array.pp new file mode 100644 index 00000000..ba65dc4d --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/array.pp @@ -0,0 +1,2 @@ +# Emulate the is_array and validate_array functions +type Stdlib::Compat::Array = Array[Any] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/bool.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/bool.pp new file mode 100644 index 00000000..5d8e27e5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/bool.pp @@ -0,0 +1,2 @@ +# Emulate the is_bool and validate_bool functions +type Stdlib::Compat::Bool = Boolean diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/float.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/float.pp new file mode 100644 index 00000000..7f98bd27 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/float.pp @@ -0,0 +1,19 @@ +# Emulate the is_float function +# The regex is what's currently used in is_float +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_float($value,) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Float $value) { +# validate_float($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Float = Variant[Float, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)(?:[eE]-?\d+)?$/]] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/integer.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/integer.pp new file mode 100644 index 00000000..e5cadb61 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/integer.pp @@ -0,0 +1,23 @@ +# Emulate the is_integer and validate_integer functions +# The regex is what's currently used in is_integer +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_integer($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Integer $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Integer = Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/], Array[Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/]]]] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/ip_address.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/ip_address.pp new file mode 100644 index 00000000..bf4c4b4f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/ip_address.pp @@ -0,0 +1 @@ +type Stdlib::Compat::Ip_address = Variant[Stdlib::Compat::Ipv4, Stdlib::Compat::Ipv6] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv4.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv4.pp new file mode 100644 index 00000000..a0ba0d6e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv4.pp @@ -0,0 +1,2 @@ +# Emulate the validate_ipv4_address and is_ipv4_address functions +type Stdlib::Compat::Ipv4 = Pattern[/^((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d)))(\/((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))|[0-9]+))?$/] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv6.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv6.pp new file mode 100644 index 00000000..18b148d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/ipv6.pp @@ -0,0 +1 @@ +type Stdlib::Compat::Ipv6 = Pattern[/^(?:(?:[\da-f]{1,4}:){7}[\da-f]{1,4}|((?:[\da-f]{1,4}:){6})(\d+)\.(\d+)\.(\d+)\.(\d+))$/] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/numeric.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/numeric.pp new file mode 100644 index 00000000..5bfc3d3e --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/numeric.pp @@ -0,0 +1,23 @@ +# Emulate the is_numeric and validate_numeric functions +# The regex is what's currently used in is_numeric +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_numeric($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Numeric $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Numeric = Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/], Array[Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/]]]] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/re.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/re.pp new file mode 100644 index 00000000..e4b5f30f --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/re.pp @@ -0,0 +1,3 @@ +# Emulate the validate_re function +# validate_re(value, re) translates to Pattern[re], which is not directly mappable as a type alias, but can be specified as Pattern[re]. +# Therefore this needs to be translated directly. diff --git a/tools/laptop_puppetisation/modules/stdlib/types/compat/string.pp b/tools/laptop_puppetisation/modules/stdlib/types/compat/string.pp new file mode 100644 index 00000000..b06255de --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/compat/string.pp @@ -0,0 +1,2 @@ +# Emulate the is_string and validate_string functions +type Stdlib::Compat::String = Optional[String] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/httpsurl.pp b/tools/laptop_puppetisation/modules/stdlib/types/httpsurl.pp new file mode 100644 index 00000000..36fd30f3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/httpsurl.pp @@ -0,0 +1 @@ +type Stdlib::HTTPSUrl = Pattern[/^https:\/\//] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/httpurl.pp b/tools/laptop_puppetisation/modules/stdlib/types/httpurl.pp new file mode 100644 index 00000000..0d93a95b --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/httpurl.pp @@ -0,0 +1 @@ +type Stdlib::HTTPUrl = Pattern[/^https?:\/\//] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/unixpath.pp b/tools/laptop_puppetisation/modules/stdlib/types/unixpath.pp new file mode 100644 index 00000000..76f2c178 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/unixpath.pp @@ -0,0 +1,2 @@ +# this regex rejects any path component that is a / or a NUL +type Stdlib::Unixpath = Pattern[/^\/([^\/\0]+(\/)?)+$/] diff --git a/tools/laptop_puppetisation/modules/stdlib/types/windowspath.pp b/tools/laptop_puppetisation/modules/stdlib/types/windowspath.pp new file mode 100644 index 00000000..bc1ee9c9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/stdlib/types/windowspath.pp @@ -0,0 +1 @@ +type Stdlib::Windowspath = Pattern[/^(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+))/] diff --git a/tools/laptop_puppetisation/modules/vcsrepo/CHANGELOG.md b/tools/laptop_puppetisation/modules/vcsrepo/CHANGELOG.md new file mode 100644 index 00000000..41e40730 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/CHANGELOG.md @@ -0,0 +1,159 @@ +# Change Log +All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [1.4.0] - Supported Release +### Summary +Small release for a new feature and added compatibility. + +### Features +- Now clone your git repository as a mirror or bare repo! +- STDERR has been added to Puppet's output +- Added Debian 8 and Ubuntu 16.04 compatibility + +## [1.3.2] - Supported Release +###Summary + +Small release for support of newer PE versions. This increments the version of PE in the metadata.json file. + +## [1.3.1] - 2015-07-28 Supported Release +###Summary +This release includes a number of bugfixes along with some test updates. + +### Fixed +- Fix for detached HEAD on git 2.4+ +- Git provider doesn't ignore revision property when depth is used (MODULES-2131) +- Test fixes +- Check if submodules == true before calling update_submodules + +## [1.3.0] - 2015-05-19 Supported Release +### Summary +This release adds git provider remote handling, svn conflict resolution, and fixes the git provider when /tmp is mounted noexec. + +### Added +- `source` property now takes a hash of sources for the git provider's remotes +- Add `submodules` parameter to skip submodule initialization for git provider +- Add `conflict` to svn provider to resolve conflicts +- Add `branch` parameter to specify clone branch +- Readme rewrite + +### Fixed +- The git provider now works even if `/tmp` is noexec + +## [1.2.0] - 2014-11-04 Supported Release +### Summary +This release includes some improvements for git, mercurial, and cvs providers, and fixes the bug where there were warnings about multiple default providers. + +### Added +- Update git and mercurial providers to set UID with `Puppet::Util::Execution.execute` instead of `su` +- Allow git excludes to be string or array +- Add `user` feature to cvs provider + +### Fixed +- No more warnings about multiple default providers! (MODULES-428) + +## [1.1.0] - 2014-07-14 Supported Release +### Summary +This release adds a Perforce provider\* and corrects the git provider behavior +when using `ensure => latest`. + +\*(Only git provider is currently supported.) + +### Added +- New Perforce provider + +### Fixed +- (MODULES-660) Fix behavior with `ensure => latest` and detached HEAD +- Spec test fixes + +## [1.0.2] - 2014-06-30 Supported Release +### Summary +This supported release adds SLES 11 to the list of compatible OSs and +documentation updates for support. + +## [1.0.1] - 2014-06-17 Supported Release +### Summary +This release is the first supported release of vcsrepo. The readme has been +greatly improved. + +### Added +- Updated and expanded readme to follow readme template + +### Fixed +- Remove SLES from compatability metadata +- Unpin rspec development dependencies +- Update acceptance level testing + +## [1.0.0] - 2014-06-04 +### Summary + +This release focuses on a number of bugfixes, and also has some +new features for Bzr and Git. + +### Added +- Bzr: + - Call set_ownership +- Git: + - Add ability for shallow clones + - Use -a and desired for HARD resets + - Use rev-parse to get tag canonical revision + +### Fixed +- HG: + - Only add ssh options when it's talking to the network +- Git: + - Fix for issue with detached HEAD + - force => true will now destroy and recreate repo + - Actually use the remote parameter + - Use origin/master instead of origin/HEAD when on master +- SVN: + - Fix svnlook behavior with plain directories + +## 0.2.0 - 2013-11-13 +### Summary + +This release mainly focuses on a number of bugfixes, which should +significantly improve the reliability of Git and SVN. Thanks to +our many contributors for all of these fixes! + +### Added +- Git: + - Add autorequire for Package['git'] +- HG: + - Allow user and identity properties. +- Bzr: + - "ensure => latest" support. +- SVN: + - Added configuration parameter. + - Add support for master svn repositories. +- CVS: + - Allow for setting the CVS_RSH environment variable. + +### Fixed +- Handle Puppet::Util[::Execution].withenv for 2.x and 3.x properly. +- Change path_empty? to not do full directory listing. +- Overhaul spec tests to work with rspec2. +- Git: + - Improve Git SSH usage documentation. + - Add ssh session timeouts to prevent network issues from blocking runs. + - Fix git provider checkout of a remote ref on an existing repo. + - Allow unlimited submodules (thanks to --recursive). + - Use git checkout --force instead of short -f everywhere. + - Update git provider to handle checking out into an existing (empty) dir. +- SVN: + - Handle force property. for svn. + - Adds support for changing upstream repo url. + - Check that the URL of the WC matches the URL from the manifest. + - Changed from using "update" to "switch". + - Handle revision update without source switch. + - Fix svn provider to look for '^Revision:' instead of '^Last Changed Rev:'. +- CVS: + - Documented the "module" attribute. + +[1.3.2]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.3.1...1.3.2 +[1.3.1]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.3.0...1.3.1 +[1.3.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.2.0...1.3.0 +[1.2.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.2...1.1.0 +[1.0.2]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/puppetlabs/puppetlabs-vcsrepo/compare/0.2.0...1.0.0 diff --git a/tools/laptop_puppetisation/modules/vcsrepo/CONTRIBUTING.md b/tools/laptop_puppetisation/modules/vcsrepo/CONTRIBUTING.md new file mode 100644 index 00000000..3c3f1e79 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/CONTRIBUTING.md @@ -0,0 +1,218 @@ +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 +% bundle exec 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 +% bundle exec rake spec_clean +% bundle exec 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://puppet.com/community/get-help) + +* [Writing tests](https://docs.puppet.com/guides/module_guides/bgtm.html#step-three-module-testing) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/tools/laptop_puppetisation/modules/vcsrepo/Gemfile b/tools/laptop_puppetisation/modules/vcsrepo/Gemfile new file mode 100644 index 00000000..c97275bd --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/Gemfile @@ -0,0 +1,48 @@ +#This file is generated by ModuleSync, do not edit. + +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +def location_from_env(env, default_location = []) + if location = ENV[env] + if location =~ /^((?:git|https?)[:@][^#]*)#(.*)/ + [{ :git => $1, :branch => $2, :require => false }] + elsif location =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [location, { :require => false }] + end + else + default_location + end +end + +group :development, :unit_tests do + gem 'metadata-json-lint' + gem 'puppet_facts' + gem 'puppet-blacksmith', '>= 3.4.0' + gem 'puppetlabs_spec_helper', '>= 1.2.1' + gem 'rspec-puppet', '>= 2.3.2' + gem 'rspec-puppet-facts' + gem 'simplecov' + gem 'parallel_tests' + gem 'rubocop', '0.41.2' if RUBY_VERSION < '2.0.0' + gem 'rubocop' if RUBY_VERSION >= '2.0.0' + gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' + gem 'json_pure', '<= 2.0.1' if RUBY_VERSION < '2.0.0' +end +group :system_tests do + gem 'beaker', *location_from_env('BEAKER_VERSION', []) if RUBY_VERSION >= '2.3.0' + gem 'beaker', *location_from_env('BEAKER_VERSION', ['< 3']) if RUBY_VERSION < '2.3.0' + gem 'beaker-rspec', *location_from_env('BEAKER_RSPEC_VERSION', ['>= 3.4']) + gem 'serverspec' + gem 'beaker-puppet_install_helper' + gem 'master_manipulator' + gem 'beaker-hostgenerator', *location_from_env('BEAKER_HOSTGENERATOR_VERSION', []) +end + +gem 'facter', *location_from_env('FACTER_GEM_VERSION') +gem 'puppet', *location_from_env('PUPPET_GEM_VERSION') + +if File.exists? "#{__FILE__}.local" + eval(File.read("#{__FILE__}.local"), binding) +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/LICENSE b/tools/laptop_puppetisation/modules/vcsrepo/LICENSE new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/tools/laptop_puppetisation/modules/vcsrepo/NOTICE b/tools/laptop_puppetisation/modules/vcsrepo/NOTICE new file mode 100644 index 00000000..7eab165b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/NOTICE @@ -0,0 +1,20 @@ +vcsrepo puppet module + +Copyright (C) 2010-2012 Puppet Labs Inc. + +Puppet Labs can be contacted at: info@puppetlabs.com + + +This program and entire repository is free software; you can +redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software +Foundation; either version 2 of the License, or any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/tools/laptop_puppetisation/modules/vcsrepo/README.markdown b/tools/laptop_puppetisation/modules/vcsrepo/README.markdown new file mode 100644 index 00000000..ffc2d7e0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/README.markdown @@ -0,0 +1,758 @@ +#vcsrepo + +####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 vcsrepo](#setup) + * [Setup requirements](#setup-requirements) + * [Beginning with vcsrepo](#beginning-with-vcsrepo) +4. [Usage - Configuration options and additional functionality](#usage) + * [Git](#git) + * [Bazaar](#bazaar) + * [CVS](#cvs) + * [Mercurial](#mercurial) + * [Perforce](#perforce) + * [Subversion](#subversion) +5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) + * [Type: vcsrepo](#type-vcsrepo) + * [Providers](#providers) + * [Features](#features) + * [Parameters](#parameters) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) + +##Overview + +The vcsrepo module lets you use Puppet to easily deploy content from your version control system (VCS). + +##Module Description + +The vcsrepo module provides a single type with providers to support the following version control systems: + +* [Git](#git) +* [Bazaar](#bazaar) +* [CVS](#cvs) +* [Mercurial](#mercurial) +* [Perforce](#perforce) +* [Subversion](#subversion) + +**Note:** `git` is the only vcs provider officially [supported by Puppet Labs](https://forge.puppetlabs.com/supported). + +##Setup + +###Setup Requirements + +The `vcsrepo` module does not install any VCS software for you. You must install a VCS before you can use this module. + +Like Puppet in general, the `vcsrepo` module does not automatically create parent directories for the files it manages. Make sure to set up any needed directory structures before you get started. + +###Beginning with vcsrepo + +To create and manage a blank repository, define the type `vcsrepo` with a path to your repository and supply the `provider` parameter based on the [VCS you're using](#usage). + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, +} +~~~ + +##Usage + +**Note:** `git` is the only vcsrepo provider officially [supported by Puppet Labs](https://forge.puppetlabs.com/supported). + +###Git + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, +} +~~~ + +If you're managing a central or official repository, you might want to make it a bare repository. To do this, set `ensure` to 'bare': + +~~~ +vcsrepo { '/path/to/repo': + ensure => bare, + provider => git, +} +~~~ + +####Clone/pull a repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', +} +~~~ + +If you want to clone your repository as bare or mirror, you can set `ensure` to 'bare' or 'mirror': + +~~~ +vcsrepo { '/path/to/repo': + ensure => mirror, + provider => git, + source => 'git://example.com/repo.git', +} +~~~ + +By default, `vcsrepo` will use the HEAD of the source repository's master branch. To use another branch or a specific commit, set `revision` to either a branch name or a commit SHA or tag. + +Branch name: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => 'development', +} +~~~ + +SHA: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', +} +~~~ + +Tag: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '1.1.2rc1', +} +~~~ + +To check out a branch as a specific user, supply the `user` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + source => 'git://example.com/repo.git', + revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31', + user => 'someUser', +} +~~~ + +To keep the repository at the latest revision, set `ensure` to 'latest'. + +**WARNING:** this overwrites any local changes to the repository: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + revision => 'master', +} +~~~ + +To clone the repository but skip initializing submodules, set `submodules` to 'false': + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://example.com/repo.git', + submodules => false, +} +~~~ + +####Use multiple remotes with a repository +In place of a single string, you can set `source` to a hash of one or more name => URL pairs: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => git, + remote => 'origin' + source => { + 'origin' => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git', + 'other_remote' => 'https://github.com/other_user/puppetlabs-vcsrepo.git' + }, +} +~~~ + +**Note:** if you set `source` to a hash, one of the names you specify must match the value of the `remote` parameter. That remote serves as the upstream of your managed repository. + +####Connect via SSH + +To connect to your source repository via SSH (e.g., 'username@server:…'), we recommend managing your SSH keys with Puppet and using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure they are present before the `vcsrepo` resource is applied. + +To use SSH keys associated with a user, specify the username in the `user` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => git, + source => 'git://username@example.com/repo.git', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Bazaar + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, +} +~~~ + +####Branch from an existing repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, + source => '/some/path', +} +~~~ + +To branch from a specific revision, set `revision` to a valid [Bazaar revision spec](http://wiki.bazaar.canonical.com/BzrRevisionSpec): + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => bzr, + source => '/some/path', + revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'bzr+ssh://...'` or `'sftp://...,'`), we recommend using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => bzr, + source => 'bzr+ssh://bzr.example.com/some/path', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###CVS + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => cvs, +} +~~~ + +####Checkout/update from a repository + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@example.com:/sources/myproj', +} +~~~ + +To get a specific module on the current mainline, supply the `module` parameter: + +~~~ +vcsrepo {'/vagrant/lockss-daemon-source': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss', + module => 'lockss-daemon', +} +~~~ + +To set the GZIP compression levels for your repository history, use the `compression` parameter: + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', +} +~~~ + +To get a specific revision, set `revision` to the revision number. + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', + revision => '1.2', +} +~~~ + +You can also set `revision` to a tag: + +~~~ +vcsrepo { '/path/to/workspace': + ensure => present, + provider => cvs, + compression => 3, + source => ':pserver:anonymous@example.com:/sources/myproj', + revision => 'SOMETAG', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH, we recommend using the [`require`](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) metaparameter to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => cvs, + source => ':pserver:anonymous@example.com:/sources/myproj', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Mercurial + +####Create a blank repository + +To create a blank repository, suitable for use as a central repository, define `vcsrepo` without `source` or `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, +} +~~~ + +####Clone/pull & update a repository + +To get the default branch tip: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', +} +~~~ + +For a specific changeset, use `revision`: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + revision => '21ea4598c962', +} +~~~ + +You can also set `revision` to a tag: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + revision => '1.1.2', +} +~~~ + +To check out as a specific user: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'http://hg.example.com/myrepo', + user => 'user', +} +~~~ + +To specify an SSH identity key: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => hg, + source => 'ssh://hg@hg.example.com/myrepo', + identity => '/home/user/.ssh/id_dsa1, +} +~~~ + +To specify a username and password for HTTP Basic authentication: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => hg, + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'ssh://...'`), we recommend using the [`require` metaparameter](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => hg, + source => 'ssh://hg.example.com//path/to/myrepo', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +###Perforce + +####Create an empty workspace + +To set up the connection to your Perforce service, set `p4config` to the location of a valid Perforce [config file](http://www.perforce.com/perforce/doc.current/manuals/p4guide/chapter.configuration.html#configuration.settings.configfiles) stored on the node: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + p4config => '/root/.p4config' +} +~~~ + +**Note:** If you don't include the `P4CLIENT` setting in your config file, the provider generates a workspace name based on the digest of `path` and the node's hostname (e.g., `puppet-91bc00640c4e5a17787286acbe2c021c`): + +####Create/update and sync a Perforce workspace + +To sync a depot path to head, set `ensure` to 'latest': + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => p4, + source => '//depot/branch/...' +} +~~~ + +To sync to a specific changelist, specify its revision number with the `revision` parameter: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => '2341' +} +~~~ + +You can also set `revision` to a label: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => p4, + source => '//depot/branch/...', + revision => 'my_label' +} +~~~ + +###Subversion + +####Create a blank repository + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, +} +~~~ + +####Check out from an existing repository + +Provide a `source` pointing to the branch or tag you want to check out: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', +} +~~~ + +You can also designate a specific revision: + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', + revision => '1234', +} +~~~ + +####Use a specific Subversion configuration directory + +Use the `configuration` parameter to designate the directory that contains your Subversion configuration files (typically, '/path/to/.subversion'): + +~~~ +vcsrepo { '/path/to/repo': + ensure => present, + provider => svn, + source => 'svn://svnrepo/hello/branches/foo', + configuration => '/path/to/.subversion', +} +~~~ + +####Connect via SSH + +To connect to your source repository via SSH (e.g., `'svn+ssh://...'`), we recommend using the [`require` metaparameter](http://docs.puppetlabs.com/references/stable/metaparameter.html#require) to make sure your SSH keys are present before the `vcsrepo` resource is applied: + +~~~ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => svn, + source => 'svn+ssh://svnrepo/hello/branches/foo', + user => 'toto', #uses toto's $HOME/.ssh setup + require => File['/home/toto/.ssh/id_rsa'], +} +~~~ + +##Reference + +###Type: vcsrepo + +The vcsrepo module adds only one type with several providers. Each provider abstracts a different VCS, and each provider includes a set of features according to its needs. + +####Providers + +**Note:** Not all features are available with all providers. + +#####`git` - Supports the Git VCS. + +Features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `submodules`, `user` + +Parameters: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user` + +#####`bzr` - Supports the Bazaar VCS. + +Features: `reference_tracking` + +Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `path`, `provider`, `revision`, `source` + +#####`cvs` - Supports the CVS VCS. + +Features: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`, `user` + +Parameters: `compression`, `cvs_rsh`, `ensure`, `excludes`, `force`, `group`, `module`, `owner`, `path`, `provider` + +#####`hg` - Supports the Mercurial VCS. + +Features: `reference_tracking`, `ssh_identity`, `user` + +Parameters: `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `revision`, `source`, `user` + +#####`p4` - Supports the Perforce VCS. + +Features: `p4config`, `reference_tracking` + +Parameters: `ensure`, `excludes`, `force`, `group`, `owner`, `p4config`, `path`, `provider`, `revision`, `source` + +#####`svn` - Supports the Subversion VCS. + +Features: `basic_auth`, `configuration`, `conflict`, `depth`, `filesystem_types`, `reference_tracking` + +Parameters: `basic_auth_password`, `basic_auth_username`, `configuration`, `conflict`, `ensure`, `excludes`, `force`, `fstype`, `group`, `owner`, `path`, `provider`, `revision`, `source`, `trust_server_cert` + +####Features + +**Note:** Not all features are available with all providers. + +* `bare_repositories` - Differentiates between bare repositories and those with working copies. (Available with `git`.) +* `basic_auth` - Supports HTTP Basic authentication. (Available with `svn`.) +* `conflict` - Lets you decide how to resolve any conflicts between the source repository and your working copy. (Available with `svn`.) +* `configuration` - Lets you specify the location of your configuration files. (Available with `svn`.) +* `cvs_rsh` - Understands the `CVS_RSH` environment variable. (Available with `cvs`.) +* `depth` - Supports shallow clones in `git` or sets scope limit in `svn`. (Available with `git` and `svn`.) +* `filesystem_types` - Supports multiple types of filesystem. (Available with `svn`.) +* `gzip_compression` - Supports explicit GZip compression levels. (Available with `cvs`.) +* `modules` - Lets you choose a specific repository module. (Available with `cvs`.) +* `multiple_remotes` - Tracks multiple remote repositories. (Available with `git`.) +* `reference_tracking` - Lets you track revision references that can change over time (e.g., some VCS tags and branch names). (Available with all providers) +* `ssh_identity` - Lets you specify an SSH identity file. (Available with `git` and `hg`.) +* `user` - Can run as a different user. (Available with `git`, `hg` and `cvs`.) +* `p4config` - Supports setting the `P4CONFIG` environment. (Available with `p4`.) +* `submodules` - Supports repository submodules which can be optionally initialized. (Available with `git`.) + +####Parameters + +All parameters are optional, except where specified otherwise. + +##### `basic_auth_password` + +Specifies the password for HTTP Basic authentication. (Requires the `basic_auth` feature.) Valid options: a string. Default: none. + +##### `basic_auth_username` + +Specifies the username for HTTP Basic authentication. (Requires the `basic_auth` feature.) Valid options: a string. Default: none. + +##### `compression` + +Sets the GZIP compression level for the repository history. (Requires the `gzip_compression` feature.) Valid options: an integer between 0 and 6. Default: none. + +##### `configuration` + +Sets the configuration directory to use. (Requires the `configuration` feature.) Valid options: a string containing an absolute path. Default: none. + +##### `conflict` + +Tells Subversion how to resolve any conflicts between the source repository and your working copy. (Requires the `conflict` feature.) Valid options: 'base', 'mine-full', 'theirs-full', and 'working'. Default: none. + +##### `cvs_rsh` + +Provides a value for the `CVS_RSH` environment variable. (Requires the `cvs_rsh` feature.) Valid options: a string. Default: none. + +##### `depth` + +In `git` sets the number of commits to include when creating a shallow clone. (Requires the `depth` feature.) Valid options: an integer. Default: none. + +In `svn` instructs Subversion to limit the scope of an operation to a particular tree depth. (Requires the `depth` feature.) Valid options: 'empty', 'files', 'immediates', 'infinity'. Default: none. + +##### `ensure` + +Specifies whether the repository should exist. Valid options: 'present', 'bare', 'absent', and 'latest'. Default: 'present'. + +##### `excludes` + +Lists any files the repository shouldn't track (similar to .gitignore). Valid options: a string (separate multiple values with the newline character). Default: none. + +##### `force` + +Specifies whether to delete any existing files in the repository path if creating a new repository. **Use with care.** Valid options: 'true' and 'false'. Default: 'false'. + +##### `fstype` + +Sets the filesystem type. (Requires the `filesystem_types` feature.) Valid options: 'fsfs' or 'bdb'. Default: none. + +##### `group` + +Specifies a group to own the repository files. Valid options: a string containing a group name or GID. Default: none. + +##### `identity` + +Specifies an identity file to use for SSH authentication. (Requires the `ssh_identity` feature.) Valid options: a string containing an absolute path. Default: none. + +##### `module` + +Specifies the repository module to manage. (Requires the `modules` feature.) Valid options: a string containing the name of a CVS module. Default: none. + +##### `owner` + +Specifies a user to own the repository files. Valid options: a string containing a username or UID. Default: none. + +##### `p4config` + +Specifies a config file that contains settings for connecting to the Perforce service. (Requires the `p4config` feature.) Valid options: a string containing the absolute path to a valid [Perforce config file](http://www.perforce.com/perforce/doc.current/manuals/p4guide/chapter.configuration.html#configuration.settings.configfiles). Default: none. + +##### `path` + +Specifies a location for the managed repository. Valid options: a string containing an absolute path. Default: the title of your declared resource. + +##### `provider` + +*Required.* Specifies the backend to use for this vcsrepo resource. Valid options: 'bzr', 'cvs', 'git', 'hg', 'p4', and 'svn'. + +##### `remote` + +Specifies the remote repository to track. (Requires the `multiple_remotes` feature.) Valid options: a string containing one of the remote names specified in `source`. Default: 'origin'. + +##### `revision` + +Sets the revision of the repository. Valid options vary by provider: + +* `git` - a string containing a Git branch name, or a commit SHA or tag +* `bzr` - a string containing a Bazaar [revision spec](http://wiki.bazaar.canonical.com/BzrRevisionSpec) +* `cvs` - a string containing a CVS [tag or revision number](http://www.thathost.com/wincvs-howto/cvsdoc/cvs_4.html) +* `hg` - a string containing a Mercurial [changeset ID](http://mercurial.selenic.com/wiki/ChangeSetID) or [tag](http://mercurial.selenic.com/wiki/Tag) +* `p4` - a string containing a Perforce [change number, label name, client name, or date spec](http://www.perforce.com/perforce/r12.1/manuals/cmdref/o.fspecs.html) +* `svn` - a string containing a Subversion [revision number](http://svnbook.red-bean.com/en/1.7/svn.basic.in-action.html#svn.basic.in-action.revs), [revision keyword, or revision date](http://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) + +Default: none. + +##### `source` + +Specifies a source repository to serve as the upstream for your managed repository. Default: none. Valid options vary by provider: + +* `git` - a string containing a [Git repository URL](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#_git_urls_a_id_urls_a) or a hash of name => URL mappings. See also [`remote`](#remote). +* `bzr` - a string containing a Bazaar branch location +* `cvs` - a string containing a CVS root +* `hg` - a string containing the local path or URL of a Mercurial repository +* `p4` - a string containing a Perforce depot path +* `svn` - a string containing a Subversion repository URL + +Default: none. + +##### `submodules` + +Specifies whether to initialize and update each submodule in the repository. (Requires the `submodules` feature.) Valid options: 'true' and 'false'. Default: 'true'. + +##### `trust_server_cert` + +Instructs Subversion to accept SSL server certificates issued by unknown certificate authorities. Valid options: 'true' and 'false'. Default: 'false'. + +##### `user` + +Specifies the user to run as for repository operations. (Requires the `user` feature.) Valid options: a string containing a username or UID. Default: none. + +##Limitations + +Git is the only VCS provider officially [supported](https://forge.puppetlabs.com/supported) by Puppet Labs. + +This module has been tested with Puppet 2.7 and higher. + +The module has been tested on: + +* CentOS 5/6/7 +* Debian 6/7 +* Oracle 5/6/7 +* Red Hat Enterprise Linux 5/6/7 +* Scientific Linux 5/6/7 +* SLES 10/11/12 +* Ubuntu 10.04/12.04/14.04 + +Testing on other platforms has been light and cannot be guaranteed. + +##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 of 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. + +You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing) diff --git a/tools/laptop_puppetisation/modules/vcsrepo/Rakefile b/tools/laptop_puppetisation/modules/vcsrepo/Rakefile new file mode 100755 index 00000000..3e8d4cb9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/Rakefile @@ -0,0 +1,38 @@ +require 'puppet_blacksmith/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppetlabs_spec_helper/rake_tasks' + +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') + +desc 'Generate pooler nodesets' +task :gen_nodeset do + require 'beaker-hostgenerator' + require 'securerandom' + require 'fileutils' + + agent_target = ENV['TEST_TARGET'] + if ! agent_target + STDERR.puts 'TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat-64default."' + agent_target = 'redhat-64default.' + end + + master_target = ENV['MASTER_TEST_TARGET'] + if ! master_target + STDERR.puts 'MASTER_TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat7-64mdcl"' + master_target = 'redhat7-64mdcl' + end + + targets = "#{master_target}-#{agent_target}" + cli = BeakerHostGenerator::CLI.new([targets]) + nodeset_dir = "tmp/nodesets" + nodeset = "#{nodeset_dir}/#{targets}-#{SecureRandom.uuid}.yaml" + FileUtils.mkdir_p(nodeset_dir) + File.open(nodeset, 'w') do |fh| + fh.print(cli.execute) + end + puts nodeset +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/checksums.json b/tools/laptop_puppetisation/modules/vcsrepo/checksums.json new file mode 100644 index 00000000..97cedb2a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/checksums.json @@ -0,0 +1,156 @@ +{ + "CHANGELOG.md": "98663c0428af5864e4a7b9a604766ba7", + "CONTRIBUTING.md": "b78f71c1104f00538d50ad2775f58e95", + "Gemfile": "d197734139f44a800a88d49ad4c34192", + "LICENSE": "b234ee4d69f5fce4486a80fdaf4a4263", + "NOTICE": "f1ed160eff5bb309c5cb651e6933acaa", + "README.markdown": "d0ed564dbd576d5e4940672bc62389b5", + "Rakefile": "6db744f1deed7ae0746abe59e3d50863", + "examples/bzr/branch.pp": "05c66419324a576b9b28df876673580d", + "examples/bzr/init_repo.pp": "fadd2321866ffb0aacff698d2dc1f0ca", + "examples/cvs/local.pp": "7fbde03a5c71edf168267ae42d0bbcbc", + "examples/cvs/remote.pp": "491f18f752752bec6133a88de242c44d", + "examples/git/bare_init.pp": "7cf56abffdf99f379153166f18f961f8", + "examples/git/clone.pp": "0e3181990c095efee1498ccfca5897fb", + "examples/git/shallow-clone-with-just-one-commit.pp": "457641c63a1ef28a655864b1fb785903", + "examples/git/working_copy_init.pp": "99d92d9957e78a0c03f9cbed989c79ca", + "examples/hg/clone.pp": "c92bbd704a4c2da55fff5f45955ce6d1", + "examples/hg/clone_basic_auth.pp": "62442bb1f978732a712a712f66f9adde", + "examples/hg/init_repo.pp": "bf5fa0ab48a2f5a1ccb63768d961413d", + "examples/p4/create_client.pp": "d49fc9c1dd55e01ee9344672ee890b13", + "examples/p4/delete_client.pp": "44fa9721fbb3ed469727856cddf34a9c", + "examples/p4/latest_client.pp": "4c9d7dc2cc629d2f108434c9f4b7df62", + "examples/p4/sync_client.pp": "ea6c5aea9d5acf7b39aa35e707848bab", + "examples/svn/checkout.pp": "9ef7a8fbd3a763fa3894efa864047023", + "examples/svn/server.pp": "94b26f6e50d5e411b33b1ded1bc2138a", + "lib/puppet/provider/vcsrepo/bzr.rb": "9304caa8c45685d741248fb167c47842", + "lib/puppet/provider/vcsrepo/cvs.rb": "7d793ce8de1416283f4ccc97e0806a88", + "lib/puppet/provider/vcsrepo/dummy.rb": "4490fb75f044bd43855b2962b8f6e301", + "lib/puppet/provider/vcsrepo/git.rb": "802fb72b98a4d1f8ea2d07eca967884e", + "lib/puppet/provider/vcsrepo/hg.rb": "6367eaabc97d546a530435f97b627506", + "lib/puppet/provider/vcsrepo/p4.rb": "b324e3141913337d5592ebbcb2a7544e", + "lib/puppet/provider/vcsrepo/svn.rb": "3b90aebeefa9ee717fee96e2c7ad703b", + "lib/puppet/provider/vcsrepo.rb": "dbd72590771291f1db23a41ac048ed9d", + "lib/puppet/type/vcsrepo.rb": "0a0b5e94c673fd5aa43a06f139013b76", + "metadata.json": "f009587adadc9f19de9e153a0cbbe1b7", + "spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb": "eaa8419eff123dd15e1485d2462a7ba6", + "spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb": "b7cb6c4c1852302ff2b37838548d4f22", + "spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb": "c2319ac03e26887ad4487ea3b582bbcb", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb": "a90df84a864354f445b5fe449ab88e1a", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb": "3f08ea8dfa28e4183e8eae53cea738d8", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb": "4281e7577a042387f7b6126627c5cf8e", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb": "f93372914141c2c7955a2f7ebae217ff", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb": "aef3ebf1d6178de6c279cb87d7f55df1", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb": "71ea6210e1539ea08c50d09323f772e8", + "spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb": "fdba3d8a380030fa21272c12ad688e0b", + "spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb": "4a4039969737bd25133a5534f0a1bc3a", + "spec/acceptance/beaker/git/clone/clone_file.rb": "c78e7e176f86e5ee6e24e4fcf8bc319f", + "spec/acceptance/beaker/git/clone/clone_file_path.rb": "1f599d4780927d61c9f814cbad8b46db", + "spec/acceptance/beaker/git/clone/clone_git.rb": "6273e28d6bc5a677c664b5ee82c04c65", + "spec/acceptance/beaker/git/clone/clone_http.rb": "5c8c16aeb9dea9d7ebfc53f67538242a", + "spec/acceptance/beaker/git/clone/clone_https.rb": "f4f78dea68b6200dcb2c51d22fc05fcb", + "spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb": "d8ae7f754060108776e425c0ea135d85", + "spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb": "5b04f4cb8dfd08bab991c5291d5cd92b", + "spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb": "229cf2cc88a97a5ccaa519d2f53ecd01", + "spec/acceptance/beaker/git/clone/clone_scp.rb": "58cdf39fcd490b20f2a74e1b4dd8f26e", + "spec/acceptance/beaker/git/clone/clone_ssh.rb": "23801f8fd433361ceb90871168d84a80", + "spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb": "d01c5e41b0ce9e664304e00afbfd4556", + "spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb": "0427368f2a3f740fdd34fee934f53a8a", + "spec/acceptance/beaker/git/compression/compression_0_checkout.rb": "5236bd53cdd40dca7af1fe126f5f36f7", + "spec/acceptance/beaker/git/compression/compression_1_checkout.rb": "8ec157b00fed76cfc491780024995578", + "spec/acceptance/beaker/git/compression/compression_2_checkout.rb": "6c282b8e167e63ae1726f3045b7f99f6", + "spec/acceptance/beaker/git/compression/compression_3_checkout.rb": "43d97bcc3cd3a48e8c73d20e71c324bb", + "spec/acceptance/beaker/git/compression/compression_4_checkout.rb": "96a8cba3585d0dd2c20acae67dbded29", + "spec/acceptance/beaker/git/compression/compression_5_checkout.rb": "21f944494b0f7dc2a902dddc2fbd445e", + "spec/acceptance/beaker/git/compression/compression_6_checkout.rb": "5462705b42e95be9e5ee7e5af3c7c0c0", + "spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb": "ea61e9642d9f03c44f060914e784ad87", + "spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb": "5f02f2a55386a53ea8919d010a12e390", + "spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb": "168f9801155a478e948827d74dfcfaad", + "spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb": "57ec765fd1af56c4349f9244ef285cc7", + "spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb": "5c90e119f86e6d53713e20d86ae4a71d", + "spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb": "6d91f95ae93f00b3aa0ea8dac1557eb4", + "spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb": "3184a82fc03408b3fc8fd468f184d5f1", + "spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb": "79a6b9d96c39cd68d5480fa543d336b1", + "spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb": "f2e75ec350f2e10b187ec2c1725c5307", + "spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb": "d8d70e543ce770dc1233f266f17df761", + "spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb": "e8a44d9fb3a2a938b3ca72cc05301455", + "spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb": "9b288fb24803120d31802e6ced58bdfb", + "spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb": "f4b82e2207808939bf0af441773d0eb5", + "spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb": "f0c3159f4e4a4a6422b406688693200d", + "spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb": "f081ac9386aacae08e502009d621666b", + "spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb": "0b950310690d479607a18c72bd4e73fc", + "spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb": "4a797b38219cfbc01025d8307c41cb70", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb": "c9e8dfad4c4d1b22d813eb918f679fd9", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb": "eb9feef20d2757dfa460e968b0923a79", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb": "a4a90ce2433032509947893340f786c0", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb": "fb0a32d1c5f350e3dad9494f411ac0bf", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb": "8530db58c5a1692d609d074f543b6b89", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb": "df666f26828a100784f15a62e0c61c82", + "spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb": "4adca01a2eb1668c7896876b6f32baf1", + "spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb": "ff73d9c33f9a3f07ffb4ce176534af0d", + "spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb": "09ea9d79a74210a982c2e6854208a7b8", + "spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb": "8a3ab8bae36e8bde4f160e1fb2191912", + "spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb": "de8a77d5932965a835654524aea483f3", + "spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb": "22e9b16579fe60030eee2b132d413b01", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb": "8b9636398a48b0c22e10cd40e7fdb8e2", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb": "c67049334bb0ef008d825f9eb6f47d92", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb": "647f5d426b7f42e1b24addf74aa4fc17", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb": "9b95f36fea77397f8b4de154590b39c7", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb": "9b8e07b2555399d905d7a9eb14e62a2a", + "spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb": "4cb6ced685b73b9aa21a7d2379918be8", + "spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb": "4e0a1e818ef2293264cdfdd297f7d6dd", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb": "700ffaaf392ebb4088e462fb56828cad", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb": "208a30a54bd6bb8ae97d5e93fab03dc9", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb": "63d5b3f6311a2cc599c2aab6eba8b2bd", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb": "227c1314a2505bfb2b0c06d5ebfd23c3", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb": "933d84a7d785beae101da3a0d0cea644", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb": "cc4c4ca339c528a7ee4462b5fa65eb4e", + "spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb": "b07af48689c609df8adc1d4c9716405c", + "spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb": "fad8e56f14d27105604f1f047bebcdf3", + "spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb": "a083b3b630bda231b0af38af2f63b3c1", + "spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb": "7a2825c0c8847521e5ab5b5867287ce2", + "spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb": "4e987c30e9904722ab832c7d9f44ca44", + "spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb": "f441c4c1e5ab019f068abacf6792b5cb", + "spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb": "a24d41af6331bdb7108bf5211b8aa9f7", + "spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb": "ea2719ca08404d568570f2c3f6a049dc", + "spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb": "6da26ed472baadce407ecfab47cadc0c", + "spec/acceptance/beaker_helper.rb": "400892d8f5c6b65846221cca26c15627", + "spec/acceptance/clone_repo_spec.rb": "601abe79e669f379ca1c0f5f55d16b61", + "spec/acceptance/create_repo_spec.rb": "523e498befa9a53ed7a611180056c2b4", + "spec/acceptance/files/create_git_repo.sh": "7cf4087d6e850d439364826566e506ea", + "spec/acceptance/files/server.crt": "1ec3a38a53076275c8805c706c3e6249", + "spec/acceptance/files/server.key": "7c946c812b5b0d1bc60b470ffb61ee8d", + "spec/acceptance/modules_1596_spec.rb": "b5c6905859527a5c449a9a0ec45cf9de", + "spec/acceptance/modules_1800_spec.rb": "342441f94798247f7c7a3625a9e58c46", + "spec/acceptance/modules_2326_spec.rb": "a895aca5234ccc92329e3f2fc4d4825f", + "spec/acceptance/modules_660_spec.rb": "8082e3f15301f4d26e8b4f82f57b1da2", + "spec/acceptance/modules_753_spec.rb": "5bc1a81386b20a2bc0db9189a141e975", + "spec/acceptance/nodesets/centos-7-x64.yml": "a713f3abd3657f0ae2878829badd23cd", + "spec/acceptance/nodesets/debian-8-x64.yml": "d2d2977900989f30086ad251a14a1f39", + "spec/acceptance/nodesets/default.yml": "b42da5a1ea0c964567ba7495574b8808", + "spec/acceptance/nodesets/docker/centos-7.yml": "8a3892807bdd62306ae4774f41ba11ae", + "spec/acceptance/nodesets/docker/debian-8.yml": "ac8e871d1068c96de5e85a89daaec6df", + "spec/acceptance/nodesets/docker/ubuntu-14.04.yml": "dc42ee922a96908d85b8f0f08203ce58", + "spec/acceptance/remove_repo_spec.rb": "1f3ebe0398e9a1b71e12f893b4a51c36", + "spec/acceptance/remove_repo_spec_noop.rb": "40b3b715cc7ed94e43c0109d8ac187e4", + "spec/fixtures/bzr_version_info.txt": "5edb13429faf2f0b9964b4326ef49a65", + "spec/fixtures/git_branch_a.txt": "2371229e7c1706c5ab8f90f0cd57230f", + "spec/fixtures/git_branch_feature_bar.txt": "70903a4dc56f7300fbaa54c295b52c4f", + "spec/fixtures/git_branch_none.txt": "acaa61de6a7f0f5ca39b763799dcb9a6", + "spec/fixtures/hg_parents.txt": "efc28a1bd3f1ce7fb4481f76feed3f6e", + "spec/fixtures/hg_tags.txt": "8383048b15adb3d58a92ea0c8b887537", + "spec/fixtures/svn_info.txt": "978db25720a098e5de48388fe600c062", + "spec/spec.opts": "a600ded995d948e393fbe2320ba8e51c", + "spec/spec_helper.rb": "b2db3bc02b4ac2fd5142a6621c641b07", + "spec/spec_helper_acceptance.rb": "25dcf81139a8e554a4d0b10e7e086e8a", + "spec/spec_helper_local.rb": "2dfe82e718310f9738849350e131f893", + "spec/support/filesystem_helpers.rb": "eb2a8eb3769865004c84e971ccb1396c", + "spec/support/fixture_helpers.rb": "61781d99ea201e9da6d23c64a25cc285", + "spec/unit/puppet/provider/vcsrepo/bzr_spec.rb": "736244d039ae02fe5408c5bd4f61e4d1", + "spec/unit/puppet/provider/vcsrepo/cvs_spec.rb": "adec0f4b55f984d6250e65ead818a517", + "spec/unit/puppet/provider/vcsrepo/git_spec.rb": "33b46e1d2e89835c0e4ecd212cdadfb8", + "spec/unit/puppet/provider/vcsrepo/hg_spec.rb": "b9edb0fd95f86f63ab93af2eb7031b2e", + "spec/unit/puppet/provider/vcsrepo/p4_spec.rb": "5ddd82366ab9fb8076747fbfb6cff94b", + "spec/unit/puppet/provider/vcsrepo/svn_spec.rb": "c2231e7aa838f28d0fe0f3522c1386ec", + "spec/unit/puppet/type/README.markdown": "de26a7643813abd6c2e7e28071b1ef94" +} \ No newline at end of file diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/branch.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/branch.pp new file mode 100644 index 00000000..0ed0705e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/branch.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest-bzr-branch': + ensure => present, + provider => bzr, + source => 'lp:do', + revision => '1312', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/init_repo.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/init_repo.pp new file mode 100644 index 00000000..1129dd7d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/bzr/init_repo.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-bzr-init': + ensure => present, + provider => bzr, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/local.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/local.pp new file mode 100644 index 00000000..155742e3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/local.pp @@ -0,0 +1,11 @@ +vcsrepo { '/tmp/vcstest-cvs-repo': + ensure => present, + provider => cvs, +} + +vcsrepo { '/tmp/vcstest-cvs-workspace-local': + ensure => present, + provider => cvs, + source => '/tmp/vcstest-cvs-repo', + require => Vcsrepo['/tmp/vcstest-cvs-repo'], +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/remote.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/remote.pp new file mode 100644 index 00000000..eb9665a9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/cvs/remote.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-cvs-workspace-remote': + ensure => present, + provider => cvs, + source => ':pserver:anonymous@cvs.sv.gnu.org:/sources/leetcvrt', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/git/bare_init.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/bare_init.pp new file mode 100644 index 00000000..4166f6e6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/bare_init.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-git-bare': + ensure => bare, + provider => git, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/git/clone.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/clone.pp new file mode 100644 index 00000000..b29a4fdb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/clone.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-git-clone': + ensure => present, + provider => git, + source => 'git://github.com/bruce/rtex.git', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp new file mode 100644 index 00000000..cd5a05db --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/shallow-clone-with-just-one-commit.pp @@ -0,0 +1,7 @@ +vcsrepo { '/tmp/git': + ensure => 'present', + provider => 'git', + source => 'https://github.com/git/git.git', + branch => 'v2.2.0', + depth => 1, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/git/working_copy_init.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/working_copy_init.pp new file mode 100644 index 00000000..e3352eb7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/git/working_copy_init.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-git-wc': + ensure => present, + provider => git, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone.pp new file mode 100644 index 00000000..be2d955d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest-hg-clone': + ensure => present, + provider => hg, + source => 'http://hg.basho.com/riak', + revision => 'riak-0.5.3', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone_basic_auth.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone_basic_auth.pp new file mode 100644 index 00000000..984f8eaf --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/clone_basic_auth.pp @@ -0,0 +1,7 @@ +vcsrepo { '/path/to/repo': + ensure => latest, + provider => 'hg', + source => 'http://hg.example.com/myrepo', + basic_auth_username => 'hgusername', + basic_auth_password => 'hgpassword', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/init_repo.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/init_repo.pp new file mode 100644 index 00000000..a8908040 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/hg/init_repo.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-hg-init': + ensure => present, + provider => hg, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/create_client.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/create_client.pp new file mode 100644 index 00000000..3cf91602 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/create_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/delete_client.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/delete_client.pp new file mode 100644 index 00000000..82c9c952 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/delete_client.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => absent, + provider => 'p4', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/latest_client.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/latest_client.pp new file mode 100644 index 00000000..106ef9e9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/latest_client.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => latest, + provider => 'p4', + source => '//depot/...', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/sync_client.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/sync_client.pp new file mode 100644 index 00000000..33e47317 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/p4/sync_client.pp @@ -0,0 +1,6 @@ +vcsrepo { '/tmp/vcstest/p4_client_root': + ensure => present, + provider => 'p4', + source => '//depot/...', + revision => '30', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/checkout.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/checkout.pp new file mode 100644 index 00000000..f9fc2730 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/checkout.pp @@ -0,0 +1,5 @@ +vcsrepo { '/tmp/vcstest-svn-checkout': + ensure => present, + provider => svn, + source => 'http://svn.edgewall.org/repos/babel/trunk', +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/server.pp b/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/server.pp new file mode 100644 index 00000000..de7c390f --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/examples/svn/server.pp @@ -0,0 +1,4 @@ +vcsrepo { '/tmp/vcstest-svn-server': + ensure => present, + provider => svn, +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb new file mode 100644 index 00000000..8793e632 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo.rb @@ -0,0 +1,42 @@ +require 'tmpdir' +require 'digest/md5' +require 'fileutils' + +# Abstract +class Puppet::Provider::Vcsrepo < Puppet::Provider + + private + + def set_ownership + owner = @resource.value(:owner) || nil + group = @resource.value(:group) || nil + FileUtils.chown_R(owner, group, @resource.value(:path)) + end + + def path_exists? + File.directory?(@resource.value(:path)) + end + + def path_empty? + # Path is empty if the only entries are '.' and '..' + d = Dir.new(@resource.value(:path)) + d.read # should return '.' + d.read # should return '..' + d.read.nil? + end + + # Note: We don't rely on Dir.chdir's behavior of automatically returning the + # value of the last statement -- for easier stubbing. + def at_path(&block) #:nodoc: + value = nil + Dir.chdir(@resource.value(:path)) do + value = yield + end + value + end + + def tempdir + @tempdir ||= File.join(Dir.tmpdir, 'vcsrepo-' + Digest::MD5.hexdigest(@resource.value(:path))) + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb new file mode 100644 index 00000000..797d84d2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/bzr.rb @@ -0,0 +1,93 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Bazaar repositories" + + commands :bzr => 'bzr' + has_features :reference_tracking + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + clone_repository(@resource.value(:revision)) + end + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), '.bzr')) + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def revision + at_path do + current_revid = bzr('version-info')[/^revision-id:\s+(\S+)/, 1] + desired = @resource.value(:revision) + begin + desired_revid = bzr('revision-info', desired).strip.split(/\s+/).last + rescue Puppet::ExecutionFailure + # Possible revid available during update (but definitely not current) + desired_revid = nil + end + if current_revid == desired_revid + desired + else + current_revid + end + end + end + + def revision=(desired) + at_path do + begin + bzr('update', '-r', desired) + rescue Puppet::ExecutionFailure + bzr('update', '-r', desired, ':parent') + end + end + update_owner + end + + def latest + at_path do + bzr('version-info', ':parent')[/^revision-id:\s+(\S+)/, 1] + end + end + + def latest? + at_path do + return self.revision == self.latest + end + end + + private + + def create_repository(path) + bzr('init', path) + update_owner + end + + def clone_repository(revision) + args = ['branch'] + if revision + args.push('-r', revision) + end + args.push(@resource.value(:source), + @resource.value(:path)) + bzr(*args) + update_owner + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb new file mode 100644 index 00000000..e5bde7a9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/cvs.rb @@ -0,0 +1,135 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports CVS repositories/workspaces" + + commands :cvs => 'cvs' + has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh, :user + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + checkout_repository + end + update_owner + end + + def exists? + if @resource.value(:source) + directory = File.join(@resource.value(:path), 'CVS') + else + directory = File.join(@resource.value(:path), 'CVSROOT') + end + File.directory?(directory) + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), 'CVS')) + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + Puppet.debug "Checking for updates because 'ensure => latest'" + at_path do + # We cannot use -P to prune empty dirs, otherwise + # CVS would report those as "missing", regardless + # if they have contents or updates. + is_current = (runcvs('-nq', 'update', '-d').strip == "") + if (!is_current) then Puppet.debug "There are updates available on the checkout's current branch/tag." end + return is_current + end + end + + def latest + # CVS does not have a conecpt like commit-IDs or change + # sets, so we can only have the current branch name (or the + # requested one, if that differs) as the "latest" revision. + should = @resource.value(:revision) + current = self.revision + return should != current ? should : current + end + + def revision + if !@rev + if File.exist?(tag_file) + contents = File.read(tag_file).strip + # Note: Doesn't differentiate between N and T entries + @rev = contents[1..-1] + else + @rev = 'HEAD' + end + Puppet.debug "Checkout is on branch/tag '#{@rev}'" + end + return @rev + end + + def revision=(desired) + at_path do + runcvs('update', '-dr', desired, '.') + update_owner + @rev = desired + end + end + + private + + def tag_file + File.join(@resource.value(:path), 'CVS', 'Tag') + end + + def checkout_repository + dirname, basename = File.split(@resource.value(:path)) + Dir.chdir(dirname) do + args = ['-d', @resource.value(:source)] + if @resource.value(:compression) + args.push('-z', @resource.value(:compression)) + end + args.push('checkout') + if @resource.value(:revision) + args.push('-r', @resource.value(:revision)) + end + args.push('-d', basename, module_name) + runcvs(*args) + end + end + + # When the source: + # * Starts with ':' (eg, :pserver:...) + def module_name + if (m = @resource.value(:module)) + m + elsif (source = @resource.value(:source)) + source[0, 1] == ':' ? File.basename(source) : '.' + end + end + + def create_repository(path) + runcvs('-d', path, 'init') + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + def runcvs(*args) + if @resource.value(:cvs_rsh) + Puppet.debug "Using CVS_RSH = " + @resource.value(:cvs_rsh) + e = { :CVS_RSH => @resource.value(:cvs_rsh) } + else + e = {} + end + + if @resource.value(:user) and @resource.value(:user) != Facter['id'].value + Puppet.debug "Running as user " + @resource.value(:user) + Puppet::Util::Execution.execute([:cvs, *args], :uid => @resource.value(:user), :custom_environment => e, :combine => true) + else + Puppet::Util::Execution.execute([:cvs, *args], :custom_environment => e, :combine => true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb new file mode 100644 index 00000000..27bfbbed --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/dummy.rb @@ -0,0 +1,12 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:dummy, :parent => Puppet::Provider::Vcsrepo) do + desc "Dummy default provider" + + defaultfor :feature => :posix + + def working_copy_exists? + providers = @resource.class.providers.map{|x| x.to_s}.sort.reject{|x| x == "dummy"}.join(", ") rescue "none" + raise("vcsrepo resource must have a provider, available: #{providers}") + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb new file mode 100644 index 00000000..804c740b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/git.rb @@ -0,0 +1,480 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Git repositories" + + has_command(:git, 'git') do + environment({ 'HOME' => ENV['HOME'] }) + end + + has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules + + def create + if @resource.value(:revision) and ensure_bare_or_mirror? + fail("Cannot set a revision (#{@resource.value(:revision)}) on a bare repository") + end + if !@resource.value(:source) + if @resource.value(:ensure) == :mirror + fail("Cannot init repository with mirror option, try bare instead") + end + + init_repository(@resource.value(:path)) + else + clone_repository(default_url, @resource.value(:path)) + update_remotes + + if @resource.value(:revision) + checkout + end + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true + update_submodules + end + + end + update_owner_and_excludes + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + # Checks to see if the current revision is equal to the revision on the + # remote (whether on a branch, tag, or reference) + # + # @return [Boolean] Returns true if the repo is on the latest revision + def latest? + return revision == latest_revision + end + + # Just gives the `should` value that we should be setting the repo to if + # latest? returns false + # + # @return [String] Returns the target sha/tag/branch + def latest + if not @resource.value(:revision) and branch = on_branch? + return branch + else + return @resource.value(:revision) + end + end + + # Get the current revision of the repo (tag/branch/sha) + # + # @return [String] Returns the branch/tag if the current sha matches the + # remote; otherwise returns the current sha. + def revision + #HEAD is the default, but lets just be explicit here. + get_revision('HEAD') + end + + # Is passed the desired reference, whether a tag, rev, or branch. Should + # handle transitions from a rev/branch/tag to a rev/branch/tag. Detached + # heads should be treated like bare revisions. + # + # @param [String] desired The desired revision to which the repo should be + # set. + def revision=(desired) + #just checkout tags and shas; fetch has already happened so they should be updated. + checkout(desired) + #branches require more work. + if local_branch_revision?(desired) + #reset instead of pull to avoid merge conflicts. assuming remote is + #updated and authoritative. + #TODO might be worthwhile to have an allow_local_changes param to decide + #whether to reset or pull when we're ensuring latest. + if @resource.value(:source) + at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") } + else + at_path { git_with_identity('reset', '--hard', "#{desired}") } + end + end + #TODO Would this ever reach here if it is bare? + if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true + update_submodules + end + update_owner_and_excludes + end + + def bare_exists? + bare_git_config_exists? && !working_copy_exists? + end + + def ensure_bare_or_mirror? + [:bare, :mirror].include? @resource.value(:ensure) + end + + # If :source is set to a hash (for supporting multiple remotes), + # we search for the URL for :remote. If it doesn't exist, + # we throw an error. If :source is just a string, we use that + # value for the default URL. + def default_url + if @resource.value(:source).is_a?(Hash) + if @resource.value(:source).has_key?(@resource.value(:remote)) + @resource.value(:source)[@resource.value(:remote)] + else + fail("You must specify the URL for #{@resource.value(:remote)} in the :source hash") + end + else + @resource.value(:source) + end + end + + def working_copy_exists? + if @resource.value(:source) and File.exists?(File.join(@resource.value(:path), '.git', 'config')) + File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{Regexp.escape(default_url)}/).any? + else + File.directory?(File.join(@resource.value(:path), '.git')) + end + end + + def exists? + working_copy_exists? || bare_exists? + end + + def update_remote_url(remote_name, remote_url) + do_update = false + current = git_with_identity('config', '-l') + + unless remote_url.nil? + # Check if remote exists at all, regardless of URL. + # If remote doesn't exist, add it + if not current.include? "remote.#{remote_name}.url" + git_with_identity('remote','add', remote_name, remote_url) + return true + + # If remote exists, but URL doesn't match, update URL + elsif not current.include? "remote.#{remote_name}.url=#{remote_url}" + git_with_identity('remote','set-url', remote_name, remote_url) + return true + else + return false + end + end + + end + + def update_remotes + do_update = false + + # If supplied source is a hash of remote name and remote url pairs, then + # we loop around the hash. Otherwise, we assume single url specified + # in source property + if @resource.value(:source).is_a?(Hash) + @resource.value(:source).keys.sort.each do |remote_name| + remote_url = @resource.value(:source)[remote_name] + at_path { do_update |= update_remote_url(remote_name, remote_url) } + end + else + at_path { do_update |= update_remote_url(@resource.value(:remote), @resource.value(:source)) } + end + + # If at least one remote was added or updated, then we must + # call the 'git remote update' command + if do_update == true + at_path { git_with_identity('remote','update') } + end + + end + + def update_references + at_path do + update_remotes + git_with_identity('fetch', @resource.value(:remote)) + git_with_identity('fetch', '--tags', @resource.value(:remote)) + update_owner_and_excludes + end + end + + private + + # @!visibility private + def bare_git_config_exists? + File.exist?(File.join(@resource.value(:path), 'config')) + end + + # @!visibility private + def clone_repository(source, path) + check_force + args = ['clone'] + if @resource.value(:depth) and @resource.value(:depth).to_i > 0 + args.push('--depth', @resource.value(:depth).to_s) + if @resource.value(:revision) + args.push('--branch', @resource.value(:revision).to_s) + end + end + if @resource.value(:branch) + args.push('--branch', @resource.value(:branch).to_s) + end + + case @resource.value(:ensure) + when :bare then args << '--bare' + when :mirror then args << '--mirror' + end + + if @resource.value(:remote) != 'origin' + args.push('--origin', @resource.value(:remote)) + end + if !working_copy_exists? + args.push(source, path) + Dir.chdir("/") do + git_with_identity(*args) + end + else + notice "Repo has already been cloned" + end + end + + # @!visibility private + def check_force + if path_exists? and not path_empty? + if @resource.value(:force) + notice "Removing %s to replace with vcsrepo." % @resource.value(:path) + destroy + else + raise Puppet::Error, "Could not create repository (non-repository at path)" + end + end + end + + # @!visibility private + def init_repository(path) + check_force + if @resource.value(:ensure) == :bare && working_copy_exists? + convert_working_copy_to_bare + elsif @resource.value(:ensure) == :present && bare_exists? + convert_bare_to_working_copy + else + # normal init + FileUtils.mkdir(@resource.value(:path)) + FileUtils.chown(@resource.value(:user), nil, @resource.value(:path)) if @resource.value(:user) + args = ['init'] + if @resource.value(:ensure) == :bare + args << '--bare' + end + at_path do + git_with_identity(*args) + end + end + end + + # Convert working copy to bare + # + # Moves: + # /.git + # to: + # / + # @!visibility private + def convert_working_copy_to_bare + notice "Converting working copy repository to bare repository" + FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir) + FileUtils.rm_rf(@resource.value(:path)) + FileUtils.mv(tempdir, @resource.value(:path)) + end + + # Convert bare to working copy + # + # Moves: + # / + # to: + # /.git + # @!visibility private + def convert_bare_to_working_copy + notice "Converting bare repository to working copy repository" + FileUtils.mv(@resource.value(:path), tempdir) + FileUtils.mkdir(@resource.value(:path)) + FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git')) + if commits_in?(File.join(@resource.value(:path), '.git')) + reset('HEAD') + git_with_identity('checkout', '--force') + update_owner_and_excludes + end + end + + # @!visibility private + def commits_in?(dot_git) + Dir.glob(File.join(dot_git, 'objects/info/*'), File::FNM_DOTMATCH) do |e| + return true unless %w(. ..).include?(File::basename(e)) + end + false + end + + # Will checkout a rev/branch/tag using the locally cached versions. Does not + # handle upstream branch changes + # @!visibility private + def checkout(revision = @resource.value(:revision)) + if !local_branch_revision?(revision) && remote_branch_revision?(revision) + #non-locally existant branches (perhaps switching to a branch that has never been checked out) + at_path { git_with_identity('checkout', '--force', '-b', revision, '--track', "#{@resource.value(:remote)}/#{revision}") } + else + #tags, locally existant branches (perhaps outdated), and shas + at_path { git_with_identity('checkout', '--force', revision) } + end + end + + # @!visibility private + def reset(desired) + at_path do + git_with_identity('reset', '--hard', desired) + end + end + + # @!visibility private + def update_submodules + at_path do + git_with_identity('submodule', 'update', '--init', '--recursive') + end + end + + # Determins if the branch exists at the upstream but has not yet been locally committed + # @!visibility private + def remote_branch_revision?(revision = @resource.value(:revision)) + # git < 1.6 returns '#{@resource.value(:remote)}/#{revision}' + # git 1.6+ returns 'remotes/#{@resource.value(:remote)}/#{revision}' + branch = at_path { branches.grep /(remotes\/)?#{@resource.value(:remote)}\/#{revision}$/ } + branch unless branch.empty? + end + + # Determins if the branch is already cached locally + # @!visibility private + def local_branch_revision?(revision = @resource.value(:revision)) + at_path { branches.include?(revision) } + end + + # @!visibility private + def tag_revision?(revision = @resource.value(:revision)) + at_path { tags.include?(revision) } + end + + # @!visibility private + def branches + at_path { git_with_identity('branch', '-a') }.gsub('*', ' ').split(/\n/).map { |line| line.strip } + end + + # git < 2.4 returns 'detached from' + # git 2.4+ returns 'HEAD detached at' + # @!visibility private + def on_branch? + at_path { + matches = git_with_identity('branch', '-a').match /\*\s+(.*)/ + matches[1] unless matches[1].match /(\(detached from|\(HEAD detached at|\(no branch)/ + } + end + + # @!visibility private + def tags + at_path { git_with_identity('tag', '-l') }.split(/\n/).map { |line| line.strip } + end + + # @!visibility private + def set_excludes + # Excludes may be an Array or a String. + at_path do + open('.git/info/exclude', 'w') do |f| + if @resource.value(:excludes).respond_to?(:each) + @resource.value(:excludes).each { |ex| f.puts ex } + else + f.puts @resource.value(:excludes) + end + end + end + end + + # Finds the latest revision or sha of the current branch if on a branch, or + # of HEAD otherwise. + # @note Calls create which can forcibly destroy and re-clone the repo if + # force => true + # @see get_revision + # + # @!visibility private + # @return [String] Returns the output of get_revision + def latest_revision + #TODO Why is create called here anyway? + create if @resource.value(:force) && working_copy_exists? + create if !working_copy_exists? + + if branch = on_branch? + return get_revision("#{@resource.value(:remote)}/#{branch}") + else + return get_revision + end + end + + # Returns the current revision given if the revision is a tag or branch and + # matches the current sha. If the current sha does not match the sha of a tag + # or branch, then it will just return the sha (ie, is not in sync) + # + # @!visibility private + # + # @param [String] rev The revision of which to check if it is current + # @return [String] Returns the tag/branch of the current repo if it's up to + # date; otherwise returns the sha of the requested revision. + def get_revision(rev = 'HEAD') + if @resource.value(:source) + update_references + else + status = at_path { git_with_identity('status')} + is_it_new = status =~ /Initial commit/ + if is_it_new + status =~ /On branch (.*)/ + branch = $1 + return branch + end + end + current = at_path { git_with_identity('rev-parse', rev).strip } + if @resource.value(:revision) + if tag_revision? + # git-rev-parse will give you the hash of the tag object itself rather + # than the commit it points to by default. Using tag^0 will return the + # actual commit. + canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:revision)}^0").strip } + elsif local_branch_revision? + canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).strip } + elsif remote_branch_revision? + canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:remote)}/#{@resource.value(:revision)}").strip } + else + #look for a sha (could match invalid shas) + canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).strip } + end + fail("#{@resource.value(:revision)} is not a local or remote ref") if canonical.nil? or canonical.empty? + current = @resource.value(:revision) if current == canonical + end + return current + end + + # @!visibility private + def update_owner_and_excludes + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + if @resource.value(:excludes) + set_excludes + end + end + + # @!visibility private + def git_with_identity(*args) + if @resource.value(:identity) + Tempfile.open('git-helper', Puppet[:statedir]) do |f| + f.puts '#!/bin/sh' + f.puts 'export SSH_AUTH_SOCKET=' + f.puts "exec ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -oConnectTimeout=120 -i #{@resource.value(:identity)} $*" + f.close + + FileUtils.chmod(0755, f.path) + env_save = ENV['GIT_SSH'] + ENV['GIT_SSH'] = f.path + + ret = git(*args) + + ENV['GIT_SSH'] = env_save + + return ret + end + elsif @resource.value(:user) and @resource.value(:user) != Facter['id'].value + env = Etc.getpwnam(@resource.value(:user)) + Puppet::Util::Execution.execute("git #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true, :custom_environment => {'HOME' => env['dir']}, :combine => true) + else + git(*args) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb new file mode 100644 index 00000000..b4269634 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/hg.rb @@ -0,0 +1,130 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Mercurial repositories" + + commands :hg => 'hg' + + has_features :reference_tracking, :ssh_identity, :user, :basic_auth + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + clone_repository(@resource.value(:revision)) + end + update_owner + end + + def working_copy_exists? + File.directory?(File.join(@resource.value(:path), '.hg')) + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + at_path do + return self.revision == self.latest + end + end + + def latest + at_path do + begin + hg_wrapper('incoming', '--branch', '.', '--newest-first', '--limit', '1', { :remote => true })[/^changeset:\s+(?:-?\d+):(\S+)/m, 1] + rescue Puppet::ExecutionFailure + # If there are no new changesets, return the current nodeid + self.revision + end + end + end + + def revision + at_path do + current = hg_wrapper('parents')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1] + desired = @resource.value(:revision) + if desired + # Return the tag name if it maps to the current nodeid + mapped = hg_wrapper('tags')[/^#{Regexp.quote(desired)}\s+\d+:(\S+)/m, 1] + if current == mapped + desired + else + current + end + else + current + end + end + end + + def revision=(desired) + at_path do + begin + hg_wrapper('pull', { :remote => true }) + rescue + end + begin + hg_wrapper('merge') + rescue Puppet::ExecutionFailure + # If there's nothing to merge, just skip + end + hg_wrapper('update', '--clean', '-r', desired) + end + update_owner + end + + private + + def create_repository(path) + hg_wrapper('init', path) + end + + def clone_repository(revision) + args = ['clone'] + if revision + args.push('-u', revision) + end + args.push(@resource.value(:source), + @resource.value(:path)) + args.push({ :remote => true }) + hg_wrapper(*args) + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + def hg_wrapper(*args) + options = { :remote => false } + if args.length > 0 and args[-1].is_a? Hash + options.merge!(args.pop) + end + + if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password) + args += [ + "--config", "\"auth.x.prefix=#{@resource.value(:source)}\"", + "--config", "\"auth.x.username=#{@resource.value(:basic_auth_username)}\"", + "--config", "\"auth.x.password=#{@resource.value(:basic_auth_password)}\"", + "--config", "\"auth.x.schemes=http https\"" + ] + end + + if options[:remote] and @resource.value(:identity) + args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"] + end + if @resource.value(:user) and @resource.value(:user) != Facter['id'].value + args.map! { |a| if a =~ /\s/ then "'#{a}'" else a end } # Adds quotes to arguments with whitespaces. + Puppet::Util::Execution.execute("hg #{args.join(' ')}", :uid => @resource.value(:user), :failonfail => true, :combine => true) + else + hg(*args) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb new file mode 100644 index 00000000..b429bcbb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/p4.rb @@ -0,0 +1,278 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Perforce depots" + + has_features :filesystem_types, :reference_tracking, :p4config + + def create + # create or update client + create_client(client_name) + + # if source provided, sync client + source = @resource.value(:source) + if source + revision = @resource.value(:revision) + sync_client(source, revision) + end + + update_owner + end + + def working_copy_exists? + # Check if the server is there, or raise error + p4(['info'], {:marshal => false}) + + # Check if workspace is setup + args = ['where'] + args.push(@resource.value(:path) + "...") + hash = p4(args, {:raise => false}) + + return (hash['code'] != "error") + end + + def exists? + working_copy_exists? + end + + def destroy + args = ['client'] + args.push('-d', '-f') + args.push(client_name) + p4(args) + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + rev = self.revision + if rev + (rev >= self.latest) + else + true + end + end + + def latest + args = ['changes'] + args.push('-m1', @resource.value(:source)) + hash = p4(args) + + return hash['change'].to_i + end + + def revision + args = ['cstat'] + args.push(@resource.value(:source)) + hash = p4(args, {:marshal => false}) + hash = marshal_cstat(hash) + + revision = 0 + if hash && hash['code'] != 'error' + hash['data'].each do |c| + if c['status'] == 'have' + change = c['change'].to_i + revision = change if change > revision + end + end + end + return revision + end + + def revision=(desired) + sync_client(@resource.value(:source), desired) + update_owner + end + + private + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end + + # Sync the client workspace files to head or specified revision. + # Params: + # +source+:: Depot path to sync + # +revision+:: Perforce change list to sync to (optional) + def sync_client(source, revision) + Puppet.debug "Syncing: #{source}" + args = ['sync'] + if revision + args.push(source + "@#{revision}") + else + args.push(source) + end + p4(args) + end + + # Returns the name of the Perforce client workspace + def client_name + p4config = @resource.value(:p4config) + + # default (generated) client name + path = @resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + # check config for client name + set_client = nil + if p4config && File.file?(p4config) + open(p4config) do |f| + m = f.grep(/^P4CLIENT=/).pop + p = /^P4CLIENT=(.*)$/ + set_client = p.match(m)[1] if m + end + end + + return set_client || ENV['P4CLIENT'] || default + end + + # Create (or update) a client workspace spec. + # If a client name is not provided then a hash based on the path is used. + # Params: + # +client+:: Name of client workspace + # +path+:: The Root location of the Perforce client workspace + def create_client(client) + Puppet.debug "Creating client: #{client}" + + # fetch client spec + hash = parse_client(client) + hash['Root'] = @resource.value(:path) + hash['Description'] = "Generated by Puppet VCSrepo" + + # check is source is a Stream + source = @resource.value(:source) + if source + parts = source.split(/\//) + if parts && parts.length >= 4 + source = "//" + parts[2] + "/" + parts[3] + streams = p4(['streams', source], {:raise => false}) + if streams['code'] == "stat" + hash['Stream'] = streams['Stream'] + notice "Streams" + streams['Stream'].inspect + end + end + end + + # save client spec + save_client(hash) + end + + + # Fetches a client workspace spec from Perforce and returns a hash map representation. + # Params: + # +client+:: name of the client workspace + def parse_client(client) + args = ['client'] + args.push('-o', client) + hash = p4(args) + + return hash + end + + + # Saves the client workspace spec from the given hash + # Params: + # +hash+:: hash map of client spec + def save_client(hash) + spec = String.new + view = "\nView:\n" + + hash.keys.sort.each do |k| + v = hash[k] + next if( k == "code" ) + if(k.to_s =~ /View/ ) + view += "\t#{v}\n" + else + spec += "#{k.to_s}: #{v.to_s}\n" + end + end + spec += view + + args = ['client'] + args.push('-i') + p4(args, {:input => spec, :marshal => false}) + end + + # Sets Perforce Configuration environment. + # P4CLIENT generated, but overwitten if defined in config. + def config + p4config = @resource.value(:p4config) + + cfg = Hash.new + cfg.store 'P4CONFIG', p4config if p4config + cfg.store 'P4CLIENT', client_name + return cfg + end + + def p4(args, options = {}) + # Merge custom options with defaults + opts = { + :raise => true, # Raise errors + :marshal => true, # Marshal output + }.merge(options) + + cmd = ['p4'] + cmd.push '-R' if opts[:marshal] + cmd.push args + cmd_str = cmd.respond_to?(:join) ? cmd.join(' ') : cmd + + Puppet.debug "environment: #{config}" + Puppet.debug "command: #{cmd_str}" + + hash = Hash.new + Open3.popen3(config, cmd_str) do |i, o, e, t| + # Send input stream if provided + if(opts[:input]) + Puppet.debug "input:\n" + opts[:input] + i.write opts[:input] + i.close + end + + if(opts[:marshal]) + hash = Marshal.load(o) + else + hash['data'] = o.read + end + + # Raise errors, Perforce or Exec + if(opts[:raise] && !e.eof && t.value != 0) + raise Puppet::Error, "\nP4: #{e.read}" + end + if(opts[:raise] && hash['code'] == 'error' && t.value != 0) + raise Puppet::Error, "\nP4: #{hash['data']}" + end + end + + Puppet.debug "hash: #{hash}\n" + return hash + end + + # helper method as cstat does not Marshal + def marshal_cstat(hash) + data = hash['data'] + code = 'error' + + list = Array.new + change = Hash.new + data.each_line do |l| + p = /^\.\.\. (.*) (.*)$/ + m = p.match(l) + if m + change[m[1]] = m[2] + if m[1] == 'status' + code = 'stat' + list.push change + change = Hash.new + end + end + end + + hash = Hash.new + hash.store 'code', code + hash.store 'data', list + return hash + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb new file mode 100644 index 00000000..fccfaa5a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb @@ -0,0 +1,139 @@ +require File.join(File.dirname(__FILE__), '..', 'vcsrepo') + +Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) do + desc "Supports Subversion repositories" + + commands :svn => 'svn', + :svnadmin => 'svnadmin', + :svnlook => 'svnlook' + + has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict, :depth + + def create + if !@resource.value(:source) + create_repository(@resource.value(:path)) + else + checkout_repository(@resource.value(:source), + @resource.value(:path), + @resource.value(:revision), + @resource.value(:depth)) + end + update_owner + end + + def working_copy_exists? + if File.directory?(@resource.value(:path)) + # :path is an svn checkout + return true if File.directory?(File.join(@resource.value(:path), '.svn')) + if File.file?(File.join(@resource.value(:path), 'format')) + # :path is an svn server + return true if svnlook('uuid', @resource.value(:path)) + end + end + false + end + + def exists? + working_copy_exists? + end + + def destroy + FileUtils.rm_rf(@resource.value(:path)) + end + + def latest? + at_path do + (self.revision >= self.latest) and (@resource.value(:source) == self.sourceurl) + end + end + + def buildargs + args = ['--non-interactive'] + if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password) + args.push('--username', @resource.value(:basic_auth_username)) + args.push('--password', @resource.value(:basic_auth_password)) + args.push('--no-auth-cache') + end + + if @resource.value(:force) + args.push('--force') + end + + if @resource.value(:configuration) + args.push('--config-dir', @resource.value(:configuration)) + end + + if @resource.value(:trust_server_cert) != :false + args.push('--trust-server-cert') + end + + args + end + + def latest + args = buildargs.push('info', '-r', 'HEAD') + at_path do + svn(*args)[/^Revision:\s+(\d+)/m, 1] + end + end + + def sourceurl + args = buildargs.push('info') + at_path do + svn(*args)[/^URL:\s+(\S+)/m, 1] + end + end + + def revision + args = buildargs.push('info') + at_path do + svn(*args)[/^Revision:\s+(\d+)/m, 1] + end + end + + def revision=(desired) + args = if @resource.value(:source) + buildargs.push('switch', '-r', desired, @resource.value(:source)) + else + buildargs.push('update', '-r', desired) + end + + if @resource.value(:conflict) + args.push('--accept', @resource.value(:conflict)) + end + + at_path do + svn(*args) + end + update_owner + end + + private + + def checkout_repository(source, path, revision, depth) + args = buildargs.push('checkout') + if revision + args.push('-r', revision) + end + if depth + args.push('--depth', depth) + end + args.push(source, path) + svn(*args) + end + + def create_repository(path) + args = ['create'] + if @resource.value(:fstype) + args.push('--fs-type', @resource.value(:fstype)) + end + args << path + svnadmin(*args) + end + + def update_owner + if @resource.value(:owner) or @resource.value(:group) + set_ownership + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/type/vcsrepo.rb b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/type/vcsrepo.rb new file mode 100644 index 00000000..e2ef0b7e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/lib/puppet/type/vcsrepo.rb @@ -0,0 +1,248 @@ +require 'pathname' + +Puppet::Type.newtype(:vcsrepo) do + desc "A local version control repository" + + feature :gzip_compression, + "The provider supports explicit GZip compression levels" + feature :basic_auth, + "The provider supports HTTP Basic Authentication" + feature :bare_repositories, + "The provider differentiates between bare repositories + and those with working copies", + :methods => [:bare_exists?, :working_copy_exists?] + + feature :filesystem_types, + "The provider supports different filesystem types" + + feature :reference_tracking, + "The provider supports tracking revision references that can change + over time (eg, some VCS tags and branch names)" + + feature :ssh_identity, + "The provider supports a configurable SSH identity file" + + feature :user, + "The provider can run as a different user" + + feature :modules, + "The repository contains modules that can be chosen of" + + feature :multiple_remotes, + "The repository tracks multiple remote repositories" + + feature :configuration, + "The configuration directory to use" + + feature :cvs_rsh, + "The provider understands the CVS_RSH environment variable" + + feature :depth, + "The provider can do shallow clones or set scope limit" + + feature :branch, + "The name of the branch" + + feature :p4config, + "The provider understands Perforce Configuration" + + feature :submodules, + "The repository contains submodules which can be optionally initialized" + + feature :conflict, + "The provider supports automatic conflict resolution" + + ensurable do + attr_accessor :latest + + def insync?(is) + @should ||= [] + + case should + when :present + return true unless [:absent, :purged, :held].include?(is) + when :latest + if is == :latest + return true + else + return false + end + when :bare + return is == :bare + when :mirror + return is == :mirror + end + end + + newvalue :present do + notice "Creating repository from present" + provider.create + end + + newvalue :bare, :required_features => [:bare_repositories] do + if !provider.exists? + provider.create + end + end + + newvalue :mirror, :required_features => [:bare_repositories] do + if !provider.exists? + provider.create + end + end + + newvalue :absent do + provider.destroy + end + + newvalue :latest, :required_features => [:reference_tracking] do + if provider.exists? && !@resource.value(:force) + if provider.respond_to?(:update_references) + provider.update_references + end + if provider.respond_to?(:latest?) + reference = provider.latest || provider.revision + else + reference = resource.value(:revision) || provider.revision + end + notice "Updating to latest '#{reference}' revision" + provider.revision = reference + else + notice "Creating repository from latest" + provider.create + end + end + + def retrieve + prov = @resource.provider + if prov + if prov.working_copy_exists? + (@should.include?(:latest) && prov.latest?) ? :latest : :present + elsif prov.class.feature?(:bare_repositories) and prov.bare_exists? + :bare + else + :absent + end + else + raise Puppet::Error, "Could not find provider" + end + end + + end + + newparam :path do + desc "Absolute path to repository" + isnamevar + validate do |value| + path = Pathname.new(value) + unless path.absolute? + raise ArgumentError, "Path must be absolute: #{path}" + end + end + end + + newparam :source do + desc "The source URI for the repository" + end + + newparam :fstype, :required_features => [:filesystem_types] do + desc "Filesystem type" + end + + newproperty :revision do + desc "The revision of the repository" + newvalue(/^\S+$/) + end + + newparam :owner do + desc "The user/uid that owns the repository files" + end + + newparam :group do + desc "The group/gid that owns the repository files" + end + + newparam :user do + desc "The user to run for repository operations" + end + + newparam :excludes do + desc "Files to be excluded from the repository" + end + + newparam :force do + desc "Force repository creation, destroying any files on the path in the process." + newvalues(:true, :false) + defaultto false + end + + newparam :compression, :required_features => [:gzip_compression] do + desc "Compression level" + validate do |amount| + unless Integer(amount).between?(0, 6) + raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)" + end + end + end + + newparam :basic_auth_username, :required_features => [:basic_auth] do + desc "HTTP Basic Auth username" + end + + newparam :basic_auth_password, :required_features => [:basic_auth] do + desc "HTTP Basic Auth password" + end + + newparam :identity, :required_features => [:ssh_identity] do + desc "SSH identity file" + end + + newparam :module, :required_features => [:modules] do + desc "The repository module to manage" + end + + newparam :remote, :required_features => [:multiple_remotes] do + desc "The remote repository to track" + defaultto "origin" + end + + newparam :configuration, :required_features => [:configuration] do + desc "The configuration directory to use" + end + + newparam :cvs_rsh, :required_features => [:cvs_rsh] do + desc "The value to be used for the CVS_RSH environment variable." + end + + newparam :depth, :required_features => [:depth] do + desc "The value to be used to do a shallow clone." + end + + newparam :branch, :required_features => [:branch] do + desc "The name of the branch to clone." + end + + newparam :p4config, :required_features => [:p4config] do + desc "The Perforce P4CONFIG environment." + end + + newparam :submodules, :required_features => [:submodules] do + desc "Initialize and update each submodule in the repository." + newvalues(:true, :false) + defaultto true + end + + newparam :conflict do + desc "The action to take if conflicts exist between repository and working copy" + end + + newparam :trust_server_cert do + desc "Trust server certificate" + newvalues(:true, :false) + defaultto :false + end + + autorequire(:package) do + ['git', 'git-core', 'mercurial'] + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/metadata.json b/tools/laptop_puppetisation/modules/vcsrepo/metadata.json new file mode 100644 index 00000000..5613c0fa --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/metadata.json @@ -0,0 +1,79 @@ +{ + "name": "puppetlabs-vcsrepo", + "version": "1.4.0", + "author": "Puppet Labs", + "summary": "Puppet module providing a type to manage repositories from various version control systems", + "license": "GPL-2.0+", + "source": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "project_page": "https://github.com/puppetlabs/puppetlabs-vcsrepo", + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "dependencies": [ + + ], + "data_provider": null, + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "SLES", + "operatingsystemrelease": [ + "10 SP4", + "11 SP1", + "12" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7", + "8" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04", + "16.04" + ] + } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">= 3.0.0 < 5.0.0" + } + ] +} diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb new file mode 100644 index 00000000..421c5f06 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_http.rb @@ -0,0 +1,69 @@ +test_name 'C3492 - checkout with basic auth (http protocol)' +skip_test 'HTTP not supported yet for basic auth using git. See FM-1331' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + ruby = '/opt/puppet/bin/ruby' if host.is_pe? || 'ruby' + gem = '/opt/puppet/bin/gem' if host.is_pe? || 'gem' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + script =<<-EOF + require 'sinatra' + + set :bind, '0.0.0.0' + set :static, true + set :public_folder, '#{tmpdir}' + + + use Rack::Auth::Basic do |username, password| + username == '#{user}' && password == '#{password}' + end + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{gem} install sinatra") + on(host, "#{ruby} #{tmpdir}/#{http_server_script} &") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:4567/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb new file mode 100644 index 00000000..753e50ca --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/basic_auth_checkout_https.rb @@ -0,0 +1,77 @@ +test_name 'C3493 - checkout with basic auth (https protocol)' +skip_test 'waiting for CA trust solution' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_https_daemon.rb' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start https server' do + script =<<-EOF + require 'webrick' + require 'webrick/https' + + authenticate = Proc.new do |req, res| + WEBrick::HTTPAuth.basic_auth(req, res, '') do |user, password| + user == '#{user}' && password == '#{password}' + end + end + + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :DocumentRootOptions=> {:HandlerCallback => authenticate}, + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, "#{tmpdir}/#{http_server_script}", script) + on(host, "#{ruby} #{tmpdir}/#{http_server_script}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} #{tmpdir}/#{http_server_script}' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8443/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb new file mode 100644 index 00000000..3b47c485 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/basic_auth/negative/basic_auth_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3494 - checkout with basic auth (git protocol)' + +# Globals +repo_name = 'testrepo_checkout' +user = 'foo' +password = 'bar' +http_server_script = 'basic_auth_http_daemon.rb' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout with puppet using basic auth' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + basic_auth_username => '#{user}', + basic_auth_password => '#{password}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout (silent error for basic auth using git protocol)" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb new file mode 100644 index 00000000..3d2131c2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3438 - checkout a branch (file protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb new file mode 100644 index 00000000..49b034e3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3437 - checkout a branch (file path)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb new file mode 100644 index 00000000..9557de85 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_git.rb @@ -0,0 +1,53 @@ +test_name 'C3436 - checkout a branch (git protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb new file mode 100644 index 00000000..fec60e2a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_http.rb @@ -0,0 +1,61 @@ +test_name 'C3441 - checkout a branch (http protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb new file mode 100644 index 00000000..3474c73d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_https.rb @@ -0,0 +1,68 @@ +test_name 'C3442 - checkout a branch (https protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb new file mode 100644 index 00000000..493b3f49 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_scp.rb @@ -0,0 +1,59 @@ +test_name 'C3439 - checkout a branch (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb new file mode 100644 index 00000000..5195ab8c --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/branch_checkout_ssh.rb @@ -0,0 +1,59 @@ +test_name 'C3440 - checkout a branch (ssh protocol)' + +# Globals +repo_name = 'testrepo_branch_checkout' +branch = 'a_branch' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'checkout a branch with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{branch}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the #{branch} branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/#{branch}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb new file mode 100644 index 00000000..7b9e64d7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/branch_checkout/negative/branch_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3609 - checkout a branch that does not exist' + +# Globals +repo_name = 'testrepo_branch_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout branch that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => 'non_existent_branch', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master branch is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('branch not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb new file mode 100644 index 00000000..45413a96 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file.rb @@ -0,0 +1,46 @@ +test_name 'C3427 - clone (file protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb new file mode 100644 index 00000000..a57e05a4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_file_path.rb @@ -0,0 +1,46 @@ +test_name 'C3426 - clone (file path)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb new file mode 100644 index 00000000..3bceb5dd --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_git.rb @@ -0,0 +1,51 @@ +test_name 'C3425 - clone (git protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb new file mode 100644 index 00000000..f545dab3 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_http.rb @@ -0,0 +1,59 @@ +test_name 'C3430 - clone (http protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb new file mode 100644 index 00000000..8758435a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_https.rb @@ -0,0 +1,66 @@ +test_name 'C3431 - clone (https protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb new file mode 100644 index 00000000..3bc3e304 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_over_different_exiting_repo_with_force.rb @@ -0,0 +1,49 @@ +test_name 'C3511 - clone over an existing repo with force' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo with force using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify new repo has replaced old one' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo not replaced by force') if res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb new file mode 100644 index 00000000..dec275fa --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3507 - clone repo with excludes in repo' + +# Globals +repo_name = 'testrepo_with_excludes_in_repo' +exclude1 = 'file1.txt' +exclude2 ='file2.txt' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb new file mode 100644 index 00000000..ba379309 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_repo_with_excludes_not_in_repo.rb @@ -0,0 +1,46 @@ +test_name 'C3508 - clone repo with excludes not in repo' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = 'worh02o' +exclude2 ='ho398b' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}', '#{exclude2}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify exludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + fail_test('exclude not found') unless res.stdout.include? "#{exclude2}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb new file mode 100644 index 00000000..59370ebd --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_scp.rb @@ -0,0 +1,57 @@ +test_name 'C3428 - clone (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb new file mode 100644 index 00000000..5bc06ec8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/clone_ssh.rb @@ -0,0 +1,57 @@ +test_name 'C3429 - clone (ssh protocol)' + +# Globals +repo_name = 'testrepo_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'clone with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is on the master branch" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('master not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb new file mode 100644 index 00000000..1e3b4bb5 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_over_different_exiting_repo.rb @@ -0,0 +1,47 @@ +test_name 'C3482 - clone over an existing repo' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git init") + on(host, "cd #{tmpdir}/#{repo_name} && touch a && git add a && git commit -m 'a'") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone over existing repo using puppet' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + @existing_sha = res.stdout + end + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify original repo was not replaced' do + on(host, "cd #{tmpdir}/#{repo_name} && git log --pretty=format:\"%h\"") do |res| + fail_test('original repo was replaced without force') unless res.stdout.include? "#{@existing_sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb new file mode 100644 index 00000000..98053555 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/clone/negative/clone_repo_with_exec_excludes.rb @@ -0,0 +1,45 @@ +test_name 'C3509 - clone repo with excludes not in repo' +skip_test 'expectations not defined' + +# Globals +repo_name = 'testrepo_with_excludes_not_in_repo' +exclude1 = "`exec \"rm -rf /tmp\"`" + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'clone repo with excludes not in repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + excludes => [ '#{exclude1}' ], + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify excludes are known to git' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/info/exclude") do |res| + fail_test('exclude not found') unless res.stdout.include? "#{exclude1}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb new file mode 100644 index 00000000..7ac4c4a0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_0_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3495 - checkout with compression 0' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 0 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb new file mode 100644 index 00000000..8b7455d8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_1_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3496 - checkout with compression 1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb new file mode 100644 index 00000000..81d32c3f --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_2_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3497 - checkout with compression 2' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 2 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 2, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb new file mode 100644 index 00000000..12b60a37 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_3_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3498 - checkout with compression 3' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 3 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 3, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb new file mode 100644 index 00000000..66d2d5eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_4_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3499 - checkout with compression 4' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 4 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 4, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb new file mode 100644 index 00000000..b60a9f7f --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_5_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3500 - checkout with compression 5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb new file mode 100644 index 00000000..2f6b075a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/compression_6_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3501 - checkout with compression 6' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 6 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 6, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb new file mode 100644 index 00000000..e74cca92 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_7_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3503 - checkout with compression 7' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 7 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 7, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb new file mode 100644 index 00000000..59aaf219 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_alpha_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3505 - checkout with compression alpha' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression alpha with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => abcde, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb new file mode 100644 index 00000000..b989e586 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_eval_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3504 - checkout with compression 10-5' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression 10-5 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => 10-5, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb new file mode 100644 index 00000000..e1373afb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_exec_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3506 - checkout with compression exec' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression exec with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb new file mode 100644 index 00000000..1253db1d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/compression/negative/compression_negative_checkout.rb @@ -0,0 +1,43 @@ +test_name 'C3502 - checkout with compression -1' + +# Globals +repo_name = 'testrepo_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout with compression -1 with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + compression => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify git repo was checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb new file mode 100644 index 00000000..ccb8a707 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_bare_repo_that_already_exists.rb @@ -0,0 +1,40 @@ +test_name 'C3472 - create bare repo that already exists' + +# Globals +repo_name = 'testrepo_bare_repo_already_exists.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create bare repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + on(host, "mkdir #{tmpdir}/#{repo_name}") + on(host, "cd #{tmpdir}/#{repo_name} && git --bare init") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}/#{repo_name}") do |res| + fail_test "found .git for #{repo_name}" if res.stdout.include? ".git" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb new file mode 100644 index 00000000..8fb85435 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/create_repo_that_already_exists.rb @@ -0,0 +1,42 @@ +test_name 'C3470 - create repo that already exists' + +# Globals +repo_name = 'testrepo_already_exists' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + on(host, "cd #{tmpdir} && git clone file://#{tmpdir}/testrepo.git #{repo_name}") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create repo that already exists using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify repo is on master branch' do + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + assert_match(/ref: refs\/heads\/master/, stdout, "Git checkout not on master on #{host}") + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb new file mode 100644 index 00000000..5b789df1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/create/negative/create_bare_repo_specifying_revision.rb @@ -0,0 +1,38 @@ +test_name 'C3473 - create bare repo specifying revision' + +# Globals +repo_name = 'testrepo_bare.git' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'create bare repo specifying revision using puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => bare, + revision => master, + provider => git, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify repo does not contain .git directory' do + on(host, "ls -al #{tmpdir}") do |res| + fail_test "found repo for #{repo_name}" if res.stdout.include? repo_name + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb new file mode 100644 index 00000000..beea7b80 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3487 - checkout as a group (file protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb new file mode 100644 index 00000000..319a8e74 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3486 - checkout as a group (file path)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb new file mode 100644 index 00000000..e5b9cf29 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3485 - checkout as a group (git protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb new file mode 100644 index 00000000..bf86f2eb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3490 - checkout as a group (http protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb new file mode 100644 index 00000000..c4c645f9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3491 - checkout as a group (https protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb new file mode 100644 index 00000000..c65acc43 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3488 - checkout as a group (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb new file mode 100644 index 00000000..cccad19c --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/group_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3489 - checkout as a group (ssh protocol)' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create group' do + apply_manifest_on(host, "group { '#{group}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is own by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') unless res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb new file mode 100644 index 00000000..081642d9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/group_checkout/negative/group_checkout_file_non_existent_group.rb @@ -0,0 +1,51 @@ +test_name 'C3484 - checkout as a group that is not on system' + +# Globals +repo_name = 'testrepo_group_checkout' +group = 'mygroup' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete group' do + apply_manifest_on(host, "group { '#{group}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a group with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + group => '#{group}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by group #{group}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by group') if res.stdout.include? ":#{group}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb new file mode 100644 index 00000000..85f1fcc0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/negative/revision_checkout_not_exists.rb @@ -0,0 +1,46 @@ +test_name 'C3614 - checkout a revision that does not exist' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout revision that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'verify that master revision is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb new file mode 100644 index 00000000..b17dc73d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3452 - checkout a revision (file protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb new file mode 100644 index 00000000..c80eb81b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3451 - checkout a revision (file path)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify repo is checked out to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb new file mode 100644 index 00000000..69a7fe22 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3450 - checkout a revision (git protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb new file mode 100644 index 00000000..7cac163d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3455 - checkout a revision (http protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb new file mode 100644 index 00000000..1c705a5e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3456 - checkout a revision (https protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get revision sha from repo' do + on(host, "git clone https://github.com/johnduarte/testrepo.git #{tmpdir}/foo") + on(host, "git --git-dir=#{tmpdir}/foo/.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb new file mode 100644 index 00000000..b5dbd244 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3453 - checkout a revision (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb new file mode 100644 index 00000000..222653e4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/revision_checkout/revision_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3454 - checkout a revision (ssh protocol)' + +# Globals +repo_name = 'testrepo_revision_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get revision sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a revision with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{@sha}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout is set to revision #{@sha}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('revision not found') unless res.stdout.include? "#{@sha}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb new file mode 100644 index 00000000..f01a488e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_exec_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3608 - shallow clone repo depth hostile input' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => "exec 'rm -rf /tmp'", + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb new file mode 100644 index 00000000..47fb338b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_file_path.rb @@ -0,0 +1,44 @@ +test_name 'C3475 - shallow clone repo minimal depth = 1 (file path protocol)' +skip_test 'Not currently supported. See FM-1285' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'git does not support shallow clone via file path: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb new file mode 100644 index 00000000..723a0b62 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_http.rb @@ -0,0 +1,55 @@ +test_name 'C3479 - shallow clone repo minimal depth = 1 (http protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/http_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step 'git does not support shallow clone via HTTP: verify checkout is NOT created' do + on(host, "ls #{tmpdir}") do |res| + fail_test('checkout found') if res.stdout.include? "#{repo_name}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb new file mode 100644 index 00000000..869620d2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_negative_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3607 - shallow clone repo depth = -1' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => -1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb new file mode 100644 index 00000000..5da9fd7e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/negative/shallow_clone_overflow_depth.rb @@ -0,0 +1,45 @@ +test_name 'C3606 - shallow clone repo depth overflow 64bit integer' + +# Globals +repo_name = 'testrepo_shallow_clone' + +pending_test("The overflow can't be handled on some git versions") + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (bad input ignored, full clone checkedout)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 18446744073709551616, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') if res.stdout.include? "shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb new file mode 100644 index 00000000..9e2abe28 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_file.rb @@ -0,0 +1,47 @@ +test_name 'C3476 - shallow clone repo minimal depth = 1 (file protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb new file mode 100644 index 00000000..49683d24 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_git.rb @@ -0,0 +1,52 @@ +test_name 'C3474 - shallow clone repo minimal depth = 1 (git protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb new file mode 100644 index 00000000..23927287 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_https.rb @@ -0,0 +1,68 @@ +test_name 'C3480 - shallow clone repo minimal depth = 1 (https protocol)' +skip_test 'Not currently supported. See FM-1286' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'ps ax | grep "#{ruby} /tmp/https_daemon.rb" | grep -v grep | awk \'{print "kill -9 " $1}\' | sh ; sleep 1') + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb new file mode 100644 index 00000000..1d5b35a1 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_scp.rb @@ -0,0 +1,58 @@ +test_name 'C3478 - shallow clone repo minimal depth = 1 (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb new file mode 100644 index 00000000..0f00b30e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_ssh.rb @@ -0,0 +1,58 @@ +test_name 'C3477 - shallow clone repo minimal depth = 1 (ssh protocol)' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'shallow clone repo with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + depth => 1, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is shallow and of the correct depth' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow not found') unless res.stdout.include? "shallow" + end + + on(host, "wc -l #{tmpdir}/#{repo_name}/.git/shallow") do |res| + fail_test('shallow not found') unless res.stdout.include? "1 #{tmpdir}/#{repo_name}/.git/shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb new file mode 100644 index 00000000..34c624f7 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/shallow_clone/shallow_clone_zero_depth.rb @@ -0,0 +1,43 @@ +test_name 'C3404 - shallow clone repo depth = 0 non shallow' + +# Globals +repo_name = 'testrepo_shallow_clone' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'shallow clone repo with puppet (zero depth means not shallow)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + depth => 0, + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify checkout is NOT shallow' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('shallow found') if res.stdout.include? "shallow" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb new file mode 100644 index 00000000..1849f029 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/negative/tag_checkout_not_exists.rb @@ -0,0 +1,47 @@ +test_name 'C3612 - checkout a tag that does not exist' + +# Globals +repo_name = 'testrepo_tag_checkout' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout tag that does not exist with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + tag => '11111111111111111', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step 'verify that master tag is checked out' do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "cat #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "ref: refs/heads/master" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb new file mode 100644 index 00000000..9c744855 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file.rb @@ -0,0 +1,48 @@ +test_name 'C3445 - checkout a tag (file protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb new file mode 100644 index 00000000..01f319cb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_file_path.rb @@ -0,0 +1,48 @@ +test_name 'C3444 - checkout a tag (file path)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb new file mode 100644 index 00000000..42e689c8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_git.rb @@ -0,0 +1,59 @@ +test_name 'C3443 - checkout a tag (git protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb new file mode 100644 index 00000000..3ea363c4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_http.rb @@ -0,0 +1,67 @@ +test_name 'C3448 - checkout a tag (http protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb new file mode 100644 index 00000000..d508c436 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_https.rb @@ -0,0 +1,74 @@ +test_name 'C3449 - checkout a tag (https protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb new file mode 100644 index 00000000..cb96b4e2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_scp.rb @@ -0,0 +1,65 @@ +test_name 'C3446 - checkout a tag (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb new file mode 100644 index 00000000..bc416e8e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/tag_checkout/tag_checkout_ssh.rb @@ -0,0 +1,65 @@ +test_name 'C3447 - checkout a tag (ssh protocol)' + +# Globals +repo_name = 'testrepo_tag_checkout' +tag = '0.0.2' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + end + + step 'get tag sha from repo' do + on(host, "git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1") do |res| + @sha = res.stdout.chomp + end + end + + step 'checkout a tag with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + revision => '#{tag}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify checkout out tag is #{tag}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host,"git --git-dir=#{tmpdir}/#{repo_name}/.git name-rev HEAD") do |res| + fail_test('tag not found') unless res.stdout.include? "#{tag}" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb new file mode 100644 index 00000000..245e1751 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/negative/user_checkout_file_non_existent_user.rb @@ -0,0 +1,51 @@ +test_name 'C3483 - checkout as a user that is not on system' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - delete user' do + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :expect_failures => true) + end + + step "verify git checkout is NOT owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') if res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb new file mode 100644 index 00000000..ccd9ad44 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file.rb @@ -0,0 +1,53 @@ +test_name 'C3459 - checkout as a user (file protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb new file mode 100644 index 00000000..602769de --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_file_path.rb @@ -0,0 +1,53 @@ +test_name 'C3458 - checkout as a user (file path)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb new file mode 100644 index 00000000..af2ffb71 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_git.rb @@ -0,0 +1,58 @@ +test_name 'C3457 - checkout as a user (git protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start git daemon' do + install_package(host, 'git-daemon') unless host['platform'] =~ /debian|ubuntu/ + on(host, "git daemon --base-path=#{tmpdir} --export-all --reuseaddr --verbose --detach") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, 'pkill -9 git-daemon ; sleep 1') + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "git://#{host}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb new file mode 100644 index 00000000..e8713e5b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_http.rb @@ -0,0 +1,66 @@ +test_name 'C3462 - checkout as a user (http protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + + step 'setup - start http server' do + http_daemon =<<-EOF + require 'webrick' + server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}") + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/http_daemon.rb', http_daemon) + on(host, "#{ruby} /tmp/http_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/http_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "http://#{host}:8000/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb new file mode 100644 index 00000000..4e633d78 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_https.rb @@ -0,0 +1,73 @@ +test_name 'C3463 - checkout as a user (https protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + ruby = (host.is_pe? && '/opt/puppet/bin/ruby') || 'ruby' + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - start https server' do + https_daemon =<<-EOF + require 'webrick' + require 'webrick/https' + server = WEBrick::HTTPServer.new( + :Port => 8443, + :DocumentRoot => "#{tmpdir}", + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => OpenSSL::X509::Certificate.new( File.open("#{tmpdir}/server.crt").read), + :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open("#{tmpdir}/server.key").read), + :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]) + WEBrick::Daemon.start + server.start + EOF + create_remote_file(host, '/tmp/https_daemon.rb', https_daemon) + #on(host, "#{ruby} /tmp/https_daemon.rb") + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + on(host, "ps ax | grep '#{ruby} /tmp/https_daemon.rb' | grep -v grep | awk '{print \"kill -9 \" $1}' | sh ; sleep 1") + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "https://github.com/johnduarte/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb new file mode 100644 index 00000000..98efb462 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_scp.rb @@ -0,0 +1,64 @@ +test_name 'C3460 - checkout as a user (ssh protocol, scp syntax)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet (scp syntax)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "root@#{host}:#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb new file mode 100644 index 00000000..cfd521ec --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker/git/user_checkout/user_checkout_ssh.rb @@ -0,0 +1,64 @@ +test_name 'C3461 - checkout as a user (ssh protocol)' + +# Globals +repo_name = 'testrepo_user_checkout' +user = 'myuser' + +hosts.each do |host| + tmpdir = host.tmpdir('vcsrepo') + step 'setup - create repo' do + git_pkg = 'git' + if host['platform'] =~ /ubuntu-10/ + git_pkg = 'git-core' + end + install_package(host, git_pkg) + my_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..')) + scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + on(host, "cd #{tmpdir} && ./create_git_repo.sh") + end + step 'setup - establish ssh keys' do + # create ssh keys + on(host, 'yes | ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + on(host, 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys') + on(host, 'echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config') + on(host, 'chown -R root:root /root/.ssh') + end + + step 'setup - create user' do + apply_manifest_on(host, "user { '#{user}': ensure => present, }", :catch_failures => true) + end + + teardown do + on(host, "rm -fr #{tmpdir}") + apply_manifest_on(host, "file{'/root/.ssh/id_rsa': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }", :catch_failures => true) + apply_manifest_on(host, "user { '#{user}': ensure => absent, }", :catch_failures => true) + end + + step 'checkout as a user with puppet' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/#{repo_name}": + ensure => present, + source => "ssh://root@#{host}#{tmpdir}/testrepo.git", + provider => git, + owner => '#{user}', + } + EOS + + apply_manifest_on(host, pp, :catch_failures => true) + apply_manifest_on(host, pp, :catch_changes => true) + end + + step "verify git checkout is owned by user #{user}" do + on(host, "ls #{tmpdir}/#{repo_name}/.git/") do |res| + fail_test('checkout not found') unless res.stdout.include? "HEAD" + end + + on(host, "stat --format '%U:%G' #{tmpdir}/#{repo_name}/.git/HEAD") do |res| + fail_test('checkout not owned by user') unless res.stdout.include? "#{user}:" + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker_helper.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker_helper.rb new file mode 100644 index 00000000..4d232047 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/beaker_helper.rb @@ -0,0 +1,51 @@ +test_name "Installing Puppet and vcsrepo module" do + step 'install puppet' do + if @options[:provision] + # This will fail if puppet is already installed, ie --no-provision + if hosts.first.is_pe? + install_pe + else + install_puppet + on hosts, "mkdir -p #{hosts.first['distmoduledir']}" + end + end + end + + step 'Ensure we can install our module' do + hosts.each do |host| + # We ask the host to interpolate it's distmoduledir because we don't + # actually know it on Windows until we've let it redirect us (depending + # on whether we're running as a 32/64 bit process on 32/64 bit Windows + moduledir = on(host, "echo #{host['distmoduledir']}").stdout.chomp + on host, "mkdir -p #{moduledir}" + end + end + + step 'install module' do + hosts.each do |host| + proj_root = File.expand_path(File.join(File.dirname(__FILE__),'..','..')) + + # This require beaker 1.15 + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + + case fact_on(host, 'osfamily') + when 'RedHat' + install_package(host, 'git') + when 'Debian' + install_package(host, 'git-core') + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + + gitconfig = <<-EOS +[user] + email = root@localhost + name = root +EOS + create_remote_file(host, "/root/.gitconfig", gitconfig) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb new file mode 100644 index 00000000..c2345502 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/clone_repo_spec.rb @@ -0,0 +1,534 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + context 'get the current master HEAD' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/master' } + end + end + + context 'using a https source on github' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/httpstestrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/httpstestrepo/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/httpstestrepo/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/master' } + end + end + + context 'using a commit SHA' do + let (:sha) do + shell("git --git-dir=#{tmpdir}/testrepo.git rev-list HEAD | tail -1").stdout.chomp + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_sha") + end + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_sha": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => "#{sha}", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_sha/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_sha/.git/HEAD") do + it { is_expected.to contain sha } + end + end + + context 'using a tag' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_tag": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => '0.0.2', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_tag/.git") do + it { is_expected.to be_directory } + end + + it 'should have the tag as the HEAD' do + shell("git --git-dir=#{tmpdir}/testrepo_tag/.git name-rev HEAD | grep '0.0.2'") + end + end + + context 'using a branch name' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_branch": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_branch/.git") do + it { is_expected.to be_directory } + end + + describe file("#{tmpdir}/testrepo_branch/.git/HEAD") do + it { is_expected.to contain 'ref: refs/heads/a_branch' } + end + end + + context 'ensure latest with branch specified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + revision => 'a_branch', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'ensure latest with branch unspecified' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_latest": + ensure => latest, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'verifies the HEAD commit SHA on remote and local match' do + remote_commit = shell("git ls-remote file://#{tmpdir}/testrepo_latest HEAD | head -1").stdout + local_commit = shell("git --git-dir=#{tmpdir}/testrepo_latest/.git rev-parse HEAD").stdout.chomp + expect(remote_commit).to include(local_commit) + end + end + + context 'with shallow clone' do + it 'does a shallow clone' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_shallow": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + depth => '1', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_shallow/.git/shallow") do + it { is_expected.to be_file } + end + end + + context 'path is not empty and not a repository' do + before(:all) do + shell("mkdir #{tmpdir}/not_a_repo", :acceptable_exit_codes => [0,1]) + shell("touch #{tmpdir}/not_a_repo/file1.txt", :acceptable_exit_codes => [0,1]) + end + + it 'should raise an exception' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/not_a_repo": + ensure => present, + provider => git + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_failures => true) + end + end + + context 'with an owner' do + pp = <<-EOS + user { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_owner": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + owner => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_owner") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'vagrant' } + end + end + + context 'with a group' do + pp = <<-EOS + group { 'vagrant': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "/#{tmpdir}/testrepo_group": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + group => 'vagrant', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_group") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'vagrant' } + end + end + + context 'with excludes' do + it 'clones a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_excludes": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + excludes => ['exclude1.txt', 'exclude2.txt'], + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_excludes/.git/info/exclude") do + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude1.txt/ } + end + + describe '#content' do + subject { super().content } + it { is_expected.to match /exclude2.txt/ } + end + end + end + + context 'with force' do + before(:all) do + shell("mkdir -p #{tmpdir}/testrepo_force/folder") + shell("touch #{tmpdir}/testrepo_force/temp.txt") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_force": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + force => true, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_force/folder") do + it { is_expected.not_to be_directory } + end + + describe file("#{tmpdir}/testrepo_force/temp.txt") do + it { is_expected.not_to be_file } + end + + describe file("#{tmpdir}/testrepo_force/.git") do + it { is_expected.to be_directory } + end + + context 'and noop' do + before(:all) do + shell("mkdir #{tmpdir}/testrepo_already_exists") + shell("cd #{tmpdir}/testrepo_already_exists && git init") + shell("cd #{tmpdir}/testrepo_already_exists && touch a && git add a && git commit -m 'a'") + end + after(:all) do + shell("rm -rf #{tmpdir}/testrepo_already_exists") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_already_exists": + ensure => present, + source => "file://#{tmpdir}/testrepo.git", + provider => git, + force => true, + noop => true, + } + EOS + + apply_manifest(pp, :catch_changes => true) + end + end + end + + context 'as a user' do + before(:all) do + shell("chmod 707 #{tmpdir}") + pp = <<-EOS + group { 'testuser': + ensure => present, + } + user { 'testuser': + ensure => present, + groups => 'testuser', + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + user => 'testuser', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_owned_by 'testuser' } + end + + describe file("#{tmpdir}/testrepo_user") do + it { is_expected.to be_directory } + it { is_expected.to be_grouped_into 'testuser' } + end + end + + context 'non-origin remote name' do + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_remote": + ensure => present, + provider => git, + source => "file://#{tmpdir}/testrepo.git", + remote => 'testorigin', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'remote name is "testorigin"' do + shell("git --git-dir=#{tmpdir}/testrepo_remote/.git remote | grep 'testorigin'") + end + + after(:all) do + pp = 'user { "testuser": ensure => absent }' + apply_manifest(pp, :catch_failures => true) + end + end + + context 'as a user with ssh' do + before(:all) do + # create user + pp = <<-EOS + group { 'testuser-ssh': + ensure => present, + } + user { 'testuser-ssh': + ensure => present, + groups => 'testuser-ssh', + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + user => 'testuser-ssh', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + after(:all) do + pp = <<-EOS + user { 'testuser-ssh': + ensure => absent, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + end + + context 'using an identity file' do + before(:all) do + # create user + pp = <<-EOS + user { 'testuser-ssh': + ensure => present, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh_id": + ensure => present, + provider => git, + source => "testuser-ssh@localhost:#{tmpdir}/testrepo.git", + identity => '/home/testuser-ssh/.ssh/id_rsa', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/create_repo_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/create_repo_spec.rb new file mode 100644 index 00000000..53a93c97 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/create_repo_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'create a repo' do + context 'without a source' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_blank_repo": + ensure => present, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_blank_repo/") do + it 'should have zero files' do + shell("ls -1 #{tmpdir}/testrepo_blank_repo | wc -l") do |r| + expect(r.stdout).to match(/^0\n$/) + end + end + end + + describe file("#{tmpdir}/testrepo_blank_repo/.git") do + it { is_expected.to be_directory } + end + end + + context 'no source but revision provided' do + it 'should not fail (MODULES-2125)' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_blank_with_revision_repo": + ensure => present, + provider => git, + revision => 'master' + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end + + context 'bare repo' do + it 'creates a bare repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo": + ensure => bare, + provider => git, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo/config") do + it { is_expected.to contain 'bare = true' } + end + + describe file("#{tmpdir}/testrepo_bare_repo/.git") do + it { is_expected.not_to be_directory } + end + end + + context 'bare repo with a revision' do + it 'does not create a bare repo when a revision is defined' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_bare_repo_rev": + ensure => bare, + provider => git, + revision => 'master', + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + describe file("#{tmpdir}/testrepo_bare_repo_rev") do + it { is_expected.not_to be_directory } + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh new file mode 100755 index 00000000..b5e930ca --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/create_git_repo.sh @@ -0,0 +1,39 @@ +#!/bin/bash +mkdir testrepo +cd testrepo + +touch file1.txt file2.txt file3.txt +git init +echo 'change 1' > file1.txt +git add file1.txt +git commit -m 'add file1' +git tag 0.0.1 +echo 'change 2' > file2.txt +git add file2.txt +git commit -m 'add file2' +git tag 0.0.2 +echo 'change 3' > file3.txt +git add file3.txt +git commit -m 'add file3' +git tag 0.0.3 + +git checkout -b a_branch +echo 'change 4' > file4.txt +git add file4.txt +git commit -m 'add file4' +echo 'change 5' > file5.txt +git add file5.txt +git commit -m 'add file5' +echo 'change 6' > file6.txt +git add file6.txt +git commit -m 'add file6' + +git checkout master +cd .. + +git --git-dir=testrepo/.git config core.bare true +cp -r testrepo/.git testrepo.git +rm -rf testrepo +cd testrepo.git +touch git-daemon-export-ok +git update-server-info diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.crt b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.crt new file mode 100644 index 00000000..270f65c0 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAWoCCQDRobnOvvkStDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE1MDQwODE3MjM1NVoXDTI1MDQwNTE3MjM1NVowRTELMAkG +A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyRTv +uX6328aQ5Auc8PI+xNaCiE0UZNYcs+xq3AEkR/Tnz0HGXdx3+PnFG7MIRSS65hXA +VGenZk3wP4vNIe9gu+G9jtOFTJOgoOBUnJ/Hcs79Zgcmz3cAWQpqww+CZpyngUDS +msZ5HoEbNS+qaIron3IrYCgPsy1BHFs5ze7JrtcCAwEAATANBgkqhkiG9w0BAQUF +AAOBgQCaYVv8WbFbrnLMOcyjE7GjSmVh68fEN+AqntZa1Z5GOv6OQIN9mVSoNxWo +lb/9xmldfMQThgKckHHvB5Q9kf923nMQZOi8yxyaoeYWrkglkFFU/sdF6yuFBdUU +D+rXmHnS754FLTGDzESmlRVUCYuwVgrRdm+P+wu2+lZT3x85VA== +-----END CERTIFICATE----- diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.key b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.key new file mode 100644 index 00000000..b594f13e --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/files/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDJFO+5frfbxpDkC5zw8j7E1oKITRRk1hyz7GrcASRH9OfPQcZd +3Hf4+cUbswhFJLrmFcBUZ6dmTfA/i80h72C74b2O04VMk6Cg4FScn8dyzv1mBybP +dwBZCmrDD4JmnKeBQNKaxnkegRs1L6poiuifcitgKA+zLUEcWznN7smu1wIDAQAB +AoGAQPnD8OOyk5DZVuctwmn0wHQ0X8jQczkAs18MtKSlzZ6knUM6zy+jkM9c0vOK +E5Wn0xtqN5v66sL6g/4vvex1DA5Q6YsXvZ48VpVliZXXK/1pdTv0qwMyHdlBhmgJ +MhnZbyNy61QHdOTsWDR1YrELpDyFMJ9cZZD0NOnsuhd2DbECQQDq7W/zlJBZPWNR +ab2dP+HLpm/PiEBT13SuEEskh3GEEfZlwz/cGu0Z8DHA4E3Z60KFjwgnc92GNFMg +m0t3hHtpAkEA2x5PsDxBk9sWwdIvu57vjQLdotvAfyb+W9puIaZS1JRSVLTsUVEj +Y0KxgsPHtcjrVoN//zGymn4ePxWOzlrQPwJBAN5thEuZY7o6dyiD9zVFYKGSqdZS +aKV5H04Wuy6Q1pd28lWTMYlSLR8b3d+B//PN3SPbMps4BoukSvhaUG+OjdECQFzF +KZIBAPa7pJftCH6UHPIDy5ifF5H+DWUQRt6CT8FnBrCMZR1MkAH/g65Me6pwZYsc +Y73E6cxVJzMoSmz9r/sCQQCOhPflFCxZ23ocsuRBo9O/mMUDaLoHZXWuJ2DqAUN2 +mS6UUR/lpyc7Cmy0VOyhS8783D7MUfji5ddfVxb5tWgm +-----END RSA PRIVATE KEY----- diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb new file mode 100644 index 00000000..fa36285a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1596_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'force with a remote' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + # Run it twice to test for idempotency + apply_manifest(pp, :catch_failures => true) + # need to create a file to make sure we aren't destroying the repo + # because fun fact, if you call destroy/create in 'retrieve' puppet won't + # register that any changes happen, because that method isn't supposed to + # be making any changes. + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp, :catch_changes => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to be_file } + end + end + + context 'force over an existing repo' do + it 'clones from remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-vcsrepo', + force => true, + } + EOS + + pp2 = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => 'https://github.com/puppetlabs/puppetlabs-stdlib', + force => true, + } + EOS + + + apply_manifest(pp, :catch_failures => true) + # create a file to make sure we're destroying the repo + shell("touch #{tmpdir}/vcsrepo/foo") + apply_manifest(pp2, :catch_failures => true) + end + + describe file("#{tmpdir}/vcsrepo/foo") do + it { is_expected.to_not be_file } + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb new file mode 100644 index 00000000..12415e80 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_1800_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'ensure latest with no revision' do + it 'clones from default remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + shell("cd #{tmpdir}/vcsrepo; /usr/bin/git reset --hard HEAD~2") + end + + it 'updates' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => latest, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb new file mode 100644 index 00000000..601c6ff6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_2326_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones with special characters' do + + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + context 'as a user with ssh' do + before(:all) do + # create user + pp = <<-EOS + group { 'testuser-ssh': + ensure => present, + } + user { 'testuser-ssh': + ensure => present, + groups => 'testuser-ssh', + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + + # create ssh keys + shell('mkdir -p /home/testuser-ssh/.ssh') + shell('echo -e \'y\n\'|ssh-keygen -q -t rsa -f /home/testuser-ssh/.ssh/id_rsa -N ""') + + # copy public key to authorized_keys + shell('cat /home/testuser-ssh/.ssh/id_rsa.pub > /home/testuser-ssh/.ssh/authorized_keys') + shell('echo -e "Host localhost\n\tStrictHostKeyChecking no\n" > /home/testuser-ssh/.ssh/config') + shell('chown -R testuser-ssh:testuser-ssh /home/testuser-ssh/.ssh') + shell("chown testuser-ssh:testuser-ssh #{tmpdir}") + end + + it 'applies the manifest' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_user_ssh": + ensure => present, + provider => git, + source => "git+ssh://testuser-ssh@localhost#{tmpdir}/testrepo.git", + user => 'testuser-ssh', + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + after(:all) do + pp = <<-EOS + user { 'testuser-ssh': + ensure => absent, + managehome => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_660_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_660_spec.rb new file mode 100644 index 00000000..c45aa28b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_660_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'MODULES-660' do + before(:all) do + # Create testrepo.git + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + scp_to(default, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir) + shell("cd #{tmpdir} && ./create_git_repo.sh") + + # Configure testrepo.git as upstream of testrepo + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => present, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + after(:all) do + shell("rm -rf #{tmpdir}/testrepo.git") + end + + shared_examples 'switch to branch/tag/sha' do + it 'pulls the new branch commits' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => 'a_branch', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the tag' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '0.0.3', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + it 'checks out the sha' do + sha = shell("cd #{tmpdir}/testrepo && git rev-parse origin/master").stdout.chomp + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo": + ensure => latest, + provider => git, + revision => '#{sha}', + source => "file://#{tmpdir}/testrepo.git", + } + EOS + apply_manifest(pp, :expect_changes => true) + apply_manifest(pp, :catch_changes => true) + end + end + + context 'on branch' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout a_branch") + shell("cd #{tmpdir}/testrepo && git reset --hard 0.0.2") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on tag' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.1") + end + it_behaves_like 'switch to branch/tag/sha' + end + context 'on detached head' do + before :each do + shell("cd #{tmpdir}/testrepo && git checkout 0.0.2") + shell("cd #{tmpdir}/testrepo && git checkout HEAD~1") + end + it_behaves_like 'switch to branch/tag/sha' + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_753_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_753_spec.rb new file mode 100644 index 00000000..e4e332bf --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/modules_753_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'clones a remote repo' do + before(:all) do + my_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + shell("mkdir -p #{tmpdir}") # win test + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + context 'clone with single remote' do + it 'clones from default remote' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remote" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + + context 'clone with multiple remotes' do + it 'clones from default remote and adds 2 remotes to config file' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/vcsrepo": + ensure => present, + provider => git, + source => {"origin" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", "test1" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git"}, + } + EOS + + apply_manifest(pp, :catch_failures => true) + + end + + it "git config output should contain the remotes" do + shell("/usr/bin/git config -l -f #{tmpdir}/vcsrepo/.git/config") do |r| + expect(r.stdout).to match(/remote.origin.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + expect(r.stdout).to match(/remote.test1.url=https:\/\/github.com\/puppetlabs\/puppetlabs-vcsrepo.git/) + end + end + + after(:all) do + shell("rm -rf #{tmpdir}/vcsrepo") + end + + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/centos-7-x64.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 00000000..5eebdefb --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: el-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/debian-8-x64.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 00000000..fef6e63c --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/default.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/default.yml new file mode 100644 index 00000000..dba339c4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-1404-x64: + roles: + - agent + - default + platform: ubuntu-14.04-amd64 + hypervisor: vagrant + box: puppetlabs/ubuntu-14.04-64-nocm +CONFIG: + type: foss diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/centos-7.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 00000000..a3333aac --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/debian-8.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 00000000..df5c3194 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/ubuntu-14.04.yml b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/ubuntu-14.04.yml new file mode 100644 index 00000000..b1efa583 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/nodesets/docker/ubuntu-14.04.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb new file mode 100644 index 00000000..d5646b34 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'remove a repo' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'removes a repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_deleted": + ensure => absent, + provider => git, + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{tmpdir}/testrepo_deleted") do + it { is_expected.not_to be_directory } + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb new file mode 100644 index 00000000..f6bd86e9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/acceptance/remove_repo_spec_noop.rb @@ -0,0 +1,31 @@ +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('vcsrepo') + +describe 'does not remove a repo if noop' do + it 'creates a blank repo' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => present, + provider => git, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'does not remove a repo if noop' do + pp = <<-EOS + vcsrepo { "#{tmpdir}/testrepo_noop_deleted": + ensure => absent, + provider => git, + force => true, + } + EOS + + apply_manifest(pp, :catch_failures => true, :noop => true, :verbose => false) + end + + describe file("#{tmpdir}/testrepo_noop_deleted") do + it { is_expected.to be_directory } + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/bzr_version_info.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/bzr_version_info.txt new file mode 100644 index 00000000..88a56a1c --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/bzr_version_info.txt @@ -0,0 +1,5 @@ +revision-id: menesis@pov.lt-20100309191856-4wmfqzc803fj300x +date: 2010-03-09 21:18:56 +0200 +build-date: 2010-03-14 00:42:43 -0800 +revno: 2634 +branch-nick: mytest diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_a.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_a.txt new file mode 100644 index 00000000..2c99829d --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_a.txt @@ -0,0 +1,14 @@ + feature/foo + feature/bar + feature/baz + feature/quux + only/local +* master + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt new file mode 100644 index 00000000..72d5e200 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_feature_bar.txt @@ -0,0 +1,14 @@ + feature/foo +* feature/bar + feature/baz + feature/quux + only/local + master + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_none.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_none.txt new file mode 100644 index 00000000..7207c379 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/git_branch_none.txt @@ -0,0 +1,15 @@ + feature/foo + feature/bar + feature/baz + feature/quux + only/local + master +* (no branch) + refactor/foo + origin/HEAD + origin/feature/foo + origin/feature/bar + origin/feature/baz + origin/feature/quux + origin/only/remote + origin/master diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_parents.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_parents.txt new file mode 100644 index 00000000..46173df4 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_parents.txt @@ -0,0 +1,6 @@ +changeset: 3:34e6012c783a +parent: 2:21ea4598c962 +parent: 1:9d0ff0028458 +user: Test User +date: Fri Aug 07 13:13:02 2009 -0400 +summary: merge diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_tags.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_tags.txt new file mode 100644 index 00000000..53792e5a --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/hg_tags.txt @@ -0,0 +1,18 @@ +tip 1019:bca3f20b249b +0.9.1 1017:76ce7cca95d8 +0.9 1001:dbaa6f4ec585 +0.8 839:65b66ac0fc83 +0.7.1 702:e1357f00129f +0.7 561:7b2af3b4c968 +0.6.3 486:e38077f4e4aa +0.6.2 405:07bb099b7b10 +0.6.1 389:93750f3fbbe2 +0.6 369:34e6012c783a +0.5.3 321:5ffa6ae7e699 +0.5.2 318:fdc2c2e4cebe +0.5.1 315:33a5ea0cbe7a +0.5 313:47490716f4c9 +0.4 240:47fa3a14cc63 +0.3.1 132:bc231db18e1c +0.3 130:661615e510dd +0.2 81:f98d13b442f6 diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/svn_info.txt b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/svn_info.txt new file mode 100644 index 00000000..d2a975b2 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/fixtures/svn_info.txt @@ -0,0 +1,10 @@ +Path: . +URL: http://example.com/svn/trunk +Repository Root: http://example.com/svn +Repository UUID: 75246ace-e253-0410-96dd-a7613ca8dc81 +Revision: 4 +Node Kind: directory +Schedule: normal +Last Changed Author: jon +Last Changed Rev: 3 +Last Changed Date: 2008-08-07 11:34:25 -0700 (Thu, 07 Aug 2008) diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/spec.opts b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec.opts new file mode 100644 index 00000000..91cd6427 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec.opts @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper.rb new file mode 100644 index 00000000..22d5d689 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper.rb @@ -0,0 +1,8 @@ +#This file is generated by ModuleSync, do not edit. +require 'puppetlabs_spec_helper/module_spec_helper' + +# put local configuration and setup into spec_helper_local +begin + require 'spec_helper_local' +rescue LoadError +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_acceptance.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_acceptance.rb new file mode 100644 index 00000000..97c43e8c --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_acceptance.rb @@ -0,0 +1,46 @@ +require 'beaker-rspec' +require 'beaker/puppet_install_helper' + +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 + + # ensure test dependencies are available on all hosts + hosts.each do |host| + copy_module_to(host, :source => proj_root, :module_name => 'vcsrepo') + case fact_on(host, 'osfamily') + when 'RedHat' + if fact_on(host, 'operatingsystemmajrelease') == '5' + will_install_git = on(host, 'which git', :acceptable_exit_codes => [0,1]).exit_code == 1 + + if will_install_git + on host, puppet('module install stahnma-epel') + apply_manifest_on( host, 'include epel' ) + end + + end + + install_package(host, 'git') + + when 'Debian' + install_package(host, 'git-core') + + else + if !check_for_package(host, 'git') + puts "Git package is required for this module" + exit + end + end + on host, 'git config --global user.email "root@localhost"' + on host, 'git config --global user.name "root"' + end + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_local.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_local.rb new file mode 100644 index 00000000..c7d27b52 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/spec_helper_local.rb @@ -0,0 +1,7 @@ +require 'support/filesystem_helpers' +require 'support/fixture_helpers' + +RSpec.configure do |c| + c.include FilesystemHelpers + c.include FixtureHelpers +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/support/filesystem_helpers.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/support/filesystem_helpers.rb new file mode 100644 index 00000000..15e2ca75 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/support/filesystem_helpers.rb @@ -0,0 +1,18 @@ +module FilesystemHelpers + + def expects_chdir(path = resource.value(:path)) + Dir.expects(:chdir).with(path).at_least_once.yields + end + + def expects_mkdir(path = resource.value(:path)) + Dir.expects(:mkdir).with(path).at_least_once + end + + def expects_rm_rf(path = resource.value(:path)) + FileUtils.expects(:rm_rf).with(path) + end + + def expects_directory?(returns = true, path = resource.value(:path)) + File.expects(:directory?).with(path).returns(returns) + end +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/support/fixture_helpers.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/support/fixture_helpers.rb new file mode 100644 index 00000000..8a0e0a0b --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/support/fixture_helpers.rb @@ -0,0 +1,7 @@ +module FixtureHelpers + + def fixture(name, ext = '.txt') + File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', name.to_s + ext)) + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb new file mode 100644 index 00000000..b5e2f731 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/bzr_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:bzr_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :bzr, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('bzr').returns('/usr/bin/bzr') + end + + describe 'creating' do + context 'with defaults' do + it "should execute 'bzr clone -r' with the revision" do + provider.expects(:bzr).with('branch', '-r', resource.value(:revision), resource.value(:source), resource.value(:path)) + provider.create + end + end + + context 'without revision' do + it "should just execute 'bzr clone' without a revision" do + resource.delete(:revision) + provider.expects(:bzr).with('branch', resource.value(:source), resource.value(:path)) + provider.create + end + end + + context 'without source' do + it "should execute 'bzr init'" do + resource.delete(:source) + provider.expects(:bzr).with('init', resource.value(:path)) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + File.expects(:directory?).with(File.join(resource.value(:path), '.bzr')).returns(true) + provider.exists? + end + end + + describe "checking the revision property" do + before do + expects_chdir + provider.expects(:bzr).with('version-info').returns(File.read(fixtures('bzr_version_info.txt'))) + @current_revid = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' + end + + context "when given a non-revid as the resource revision" do + context "when its revid is not different than the current revid" do + it "should return the ref" do + resource[:revision] = '2634' + provider.expects(:bzr).with('revision-info', '2634').returns("2634 menesis@pov.lt-20100309191856-4wmfqzc803fj300x\n") + expect(provider.revision).to eq(resource.value(:revision)) + end + end + context "when its revid is different than the current revid" do + it "should return the current revid" do + resource[:revision] = '2636' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2635 foo\n") + expect(provider.revision).to eq(@current_revid) + end + end + end + + context "when given a revid as the resource revision" do + context "when it is the same as the current revid" do + it "should return it" do + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("1234 #{resource.value(:revision)}\n") + expect(provider.revision).to eq(resource.value(:revision)) + end + end + context "when it is not the same as the current revid" do + it "should return the current revid" do + resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300y' + provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2636 foo\n") + expect(provider.revision).to eq(@current_revid) + end + end + + end + end + + describe "setting the revision property" do + it "should use 'bzr update -r' with the revision" do + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:bzr).with('update', '-r', 'somerev') + provider.revision = 'somerev' + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb new file mode 100644 index 00000000..d7edd1df --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/cvs_spec.rb @@ -0,0 +1,124 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:cvs_provider) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :cvs, + :revision => '2634', + :source => 'lp:do', + :path => '/tmp/test', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('cvs').returns('/usr/bin/cvs') + end + + describe 'creating' do + context "with a source" do + it "should execute 'cvs checkout'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :custom_environment => {}, :combine => true) + provider.create + end + + it "should execute 'cvs checkout' as user 'muppet'" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:revision] = 'an-unimportant-value' + resource[:user] = 'muppet' + expects_chdir('/tmp') + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar'], :uid => 'muppet', :custom_environment => {}, :combine => true) + provider.create + end + + it "should just execute 'cvs checkout' without a revision" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}, :combine => true) + provider.create + end + + context "with a compression" do + it "should just execute 'cvs checkout' without a revision" do + resource[:source] = ':ext:source@example.com:/foo/bar' + resource[:compression] = '3' + resource.delete(:revision) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:source), '-z', '3', 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source))], :custom_environment => {}, :combine => true) + provider.create + end + end + end + + context "when a source is not given" do + it "should execute 'cvs init'" do + resource.delete(:source) + Puppet::Util::Execution.expects(:execute).with([:cvs, '-d', resource.value(:path), 'init'], :custom_environment => {}, :combine => true) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + provider.destroy + end + end + + describe "checking existence" do + it "should check for the CVS directory with source" do + resource[:source] = ':ext:source@example.com:/foo/bar' + File.expects(:directory?).with(File.join(resource.value(:path), 'CVS')) + provider.exists? + end + + it "should check for the CVSROOT directory without source" do + resource.delete(:source) + File.expects(:directory?).with(File.join(resource.value(:path), 'CVSROOT')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + @tag_file = File.join(resource.value(:path), 'CVS', 'Tag') + end + + context "when CVS/Tag exists" do + before do + @tag = 'TAG' + File.expects(:exist?).with(@tag_file).returns(true) + end + it "should read CVS/Tag" do + File.expects(:read).with(@tag_file).returns("T#{@tag}") + expect(provider.revision).to eq(@tag) + end + end + + context "when CVS/Tag does not exist" do + before do + File.expects(:exist?).with(@tag_file).returns(false) + end + it "assumes HEAD" do + expect(provider.revision).to eq('HEAD') + end + end + end + + describe "when setting the revision property" do + before do + @tag = 'SOMETAG' + end + + it "should use 'cvs update -dr'" do + expects_chdir + Puppet::Util::Execution.expects(:execute).with([:cvs, 'update', '-dr', @tag, '.'], :custom_environment => {}, :combine => true) + provider.revision = @tag + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb new file mode 100644 index 00000000..6a8f58f8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/git_spec.rb @@ -0,0 +1,401 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do + def branch_a_list(include_branch = nil?) + < 'test', + :ensure => :present, + :provider => :git, + :revision => '2634', + :source => 'git@repo', + :path => '/tmp/test', + :force => false + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end + + context 'creating' do + context "with a revision that is a remote branch" do + it "should execute 'git clone' and 'git checkout -b'" do + resource[:revision] = 'only/remote' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with a remote not named 'origin'" do + it "should execute 'git clone --origin not_origin" do + resource[:remote] = 'not_origin' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--origin', 'not_origin', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("not_origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with shallow clone enable" do + it "should execute 'git clone --depth 1'" do + resource[:revision] = 'only/remote' + resource[:depth] = 1 + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', '--depth', '1', '--branch', resource.value(:revision),resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "with a revision that is not a remote branch" do + it "should execute 'git clone' and 'git reset --hard'" do + resource[:revision] = 'a-commit-or-tag' + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + + it "should execute 'git clone' and submodule commands" do + resource.delete(:revision) + provider.expects(:git).with('clone', resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remotes) + provider.create + end + end + + context "with an ensure of bare" do + context "with revision" do + it "should raise an error" do + resource[:ensure] = :bare + expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i + end + end + context "without revision" do + it "should just execute 'git clone --bare'" do + resource[:ensure] = :bare + resource.delete(:revision) + provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path)) + provider.expects(:update_remotes) + provider.create + end + end + end + + context "with an ensure of mirror" do + context "with revision" do + it "should raise an error" do + resource[:ensure] = :mirror + expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i + end + end + context "without revision" do + it "should just execute 'git clone --mirror'" do + resource[:ensure] = :mirror + resource.delete(:revision) + provider.expects(:git).with('clone', '--mirror', resource.value(:source), resource.value(:path)) + provider.expects(:update_remotes) + provider.create + end + end + end + + context "when a source is not given" do + context "when the path does not exist" do + it "should execute 'git init'" do + resource[:ensure] = :present + resource.delete(:source) + expects_mkdir + expects_chdir + expects_directory?(false) + + provider.expects(:bare_exists?).returns(false) + provider.expects(:git).with('init') + provider.create + end + end + + context "when the path is a bare repository" do + it "should convert it to a working copy" do + resource[:ensure] = :present + resource.delete(:source) + provider.expects(:bare_exists?).returns(true) + provider.expects(:convert_bare_to_working_copy) + provider.create + end + end + + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) + end + end + end + + context "when the path does not exist" do + it "should execute 'git init --bare'" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + expects_chdir + expects_mkdir + expects_directory?(false) + provider.expects(:working_copy_exists?).returns(false) + provider.expects(:git).with('init', '--bare') + provider.create + end + + it "should raise an exeption" do + resource[:ensure] = :mirror + resource.delete(:source) + resource.delete(:revision) + + expect { provider.create }.to raise_error Puppet::Error, /cannot init repository with mirror.+try bare/i + end + end + + context "when the path is a working copy repository" do + it "should convert it to a bare repository" do + resource[:ensure] = :bare + resource.delete(:source) + resource.delete(:revision) + provider.expects(:working_copy_exists?).returns(true) + provider.expects(:convert_working_copy_to_bare) + provider.create + end + it "should clone overtop it using force" do + resource[:force] = true + Dir.expects(:chdir).with('/').at_least_once.yields + Dir.expects(:chdir).with('/tmp/test').at_least_once.yields + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.destroy + provider.expects(:git).with('clone',resource.value(:source), resource.value(:path)) + provider.expects(:update_submodules) + provider.expects(:update_remote_url).with("origin", resource.value(:source)).returns false + provider.expects(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.create + end + end + + context "when the path is not empty and not a repository" do + it "should raise an exception" do + provider.expects(:path_exists?).returns(true) + provider.expects(:path_empty?).returns(false) + provider.expects(:working_copy_exists?).returns(false) + expect { provider.create }.to raise_error(Puppet::Error) + end + end + end + + + context 'destroying' do + it "it should remove the directory" do + #expects_rm_rf + provider.destroy + end + end + + context "checking the revision property" do + before do + expects_chdir('/tmp/test') + resource[:revision] = 'currentsha' + resource[:source] = 'http://example.com' + provider.stubs(:git).with('config', 'remote.origin.url').returns('') + provider.stubs(:git).with('fetch', 'origin') # FIXME + provider.stubs(:git).with('fetch', '--tags', 'origin') + provider.stubs(:git).with('rev-parse', 'HEAD').returns('currentsha') + provider.stubs(:git).with('branch', '-a').returns(branch_a_list(resource.value(:revision))) + provider.stubs(:git).with('tag', '-l').returns("Hello") + end + + context "when its SHA is not different than the current SHA" do + it "should return the ref" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its SHA is different than the current SHA" do + it "should return the current SHA" do + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('othersha') + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its a ref to a remote head" do + it "should return the revision" do + provider.stubs(:git).with('branch', '-a').returns(" remotes/origin/#{resource.value(:revision)}") + provider.expects(:git).with('rev-parse', "origin/#{resource.value(:revision)}").returns("newsha") + provider.expects(:update_remotes) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when its a ref to non existant remote head" do + it "should fail" do + provider.expects(:git).with('branch', '-a').returns(branch_a_list) + provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('') + provider.expects(:update_remotes) + expect { provider.revision }.to raise_error(Puppet::Error, /not a local or remote ref$/) + end + end + + context "when the source is modified" do + it "should update the origin url" do + resource[:source] = 'git://git@foo.com/bar.git' + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when multiple sources are modified" do + it "should update the urls" do + resource[:source] = {"origin" => "git://git@foo.com/bar.git", "new_remote" => "git://git@foo.com/baz.git"} + provider.expects(:git).at_least_once.with('config', '-l').returns("remote.origin.url=git://git@foo.com/bar.git\n", "remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git') + provider.expects(:git).with('remote', 'add', 'new_remote', 'git://git@foo.com/baz.git') + provider.expects(:git).with('remote','update') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when there's no source" do + it 'should return the revision' do + resource.delete(:source) + provider.expects(:git).with('status') + provider.expects(:git).with('rev-parse', resource.value(:revision)).returns('currentsha') + expect(provider.revision).to eq(resource.value(:revision)) + end + end + end + + context "setting the revision property" do + before do + expects_chdir + end + context "when it's an existing local branch" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'feature/foo' + provider.expects(:update_submodules) + provider.expects(:git).with('branch', '-a').at_least_once.returns(branch_a_list(resource.value(:revision))) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.revision = resource.value(:revision) + end + end + context "when it's a remote branch" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'only/remote' + provider.expects(:update_submodules) + provider.expects(:git).with('branch', '-a').at_least_once.returns(resource.value(:revision)) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}") + provider.revision = resource.value(:revision) + end + end + context "when it's a commit or tag" do + it "should use 'git fetch' and 'git reset'" do + resource[:revision] = 'a-commit-or-tag' + provider.expects(:git).with('branch', '-a').at_least_once.returns(fixture(:git_branch_a)) + provider.expects(:git).with('checkout', '--force', resource.value(:revision)) + provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) + provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a)) + provider.expects(:git).with('submodule', 'update', '--init', '--recursive') + provider.revision = resource.value(:revision) + end + end + end + + context "updating references" do + it "should use 'git fetch --tags'" do + resource.delete(:source) + expects_chdir + provider.expects(:git).with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n") + provider.expects(:git).with('fetch', 'origin') + provider.expects(:git).with('fetch', '--tags', 'origin') + provider.update_references + end + end + + describe 'latest?' do + context 'when true' do + it do + provider.expects(:revision).returns('testrev') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_truthy + end + end + context 'when false' do + it do + provider.expects(:revision).returns('master') + provider.expects(:latest_revision).returns('testrev') + expect(provider.latest?).to be_falsey + end + end + end + + describe 'convert_working_copy_to_bare' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:rm_rf).returns(true) + FileUtils.expects(:mv).returns(true) + + provider.instance_eval { convert_working_copy_to_bare } + end + end + + describe 'convert_bare_to_working_copy' do + it do + FileUtils.expects(:mv).returns(true) + FileUtils.expects(:mkdir).returns(true) + FileUtils.expects(:mv).returns(true) + provider.expects(:commits_in?).returns(true) + # If you forget to stub these out you lose 3 hours of rspec work. + provider.expects(:reset).with('HEAD').returns(true) + provider.expects(:git_with_identity).returns(true) + provider.expects(:update_owner_and_excludes).returns(true) + + provider.instance_eval { convert_bare_to_working_copy } + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb new file mode 100644 index 00000000..65d820d9 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/hg_spec.rb @@ -0,0 +1,138 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:hg) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :hg, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('hg').returns('/usr/bin/hg') + end + + describe 'creating' do + context 'with source and revision' do + it "should execute 'hg clone -u' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + provider.expects(:hg).with('clone', '-u', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context 'without revision' do + it "should just execute 'hg clone' without a revision" do + resource[:source] = 'something' + provider.expects(:hg).with('clone', resource.value(:source), resource.value(:path)) + provider.create + end + end + + context "when a source is not given" do + it "should execute 'hg init'" do + provider.expects(:hg).with('init', resource.value(:path)) + provider.create + end + end + + context "when basic auth is used" do + it "should execute 'hg clone'" do + resource[:source] = 'something' + resource[:basic_auth_username] = 'user' + resource[:basic_auth_password] = 'pass' + provider.expects(:hg).with('clone', + resource.value(:source), + resource.value(:path), + "--config","\"auth.x.prefix=" + resource.value(:source) + "\"", + "--config","\"auth.x.username=" + resource.value(:basic_auth_username) + "\"", + "--config","\"auth.x.password=" + resource.value(:basic_auth_password) + "\"", + "--config","\"auth.x.schemes=http https" + "\"") + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + expects_directory?(true, File.join(resource.value(:path), '.hg')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + expects_chdir + end + + context "when given a non-SHA as the resource revision" do + before do + provider.expects(:hg).with('parents').returns(fixture(:hg_parents)) + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + end + + context "when its SHA is not different than the current SHA" do + it "should return the ref" do + resource[:revision] = '0.6' + expect(provider.revision).to eq('0.6') + end + end + + context "when its SHA is different than the current SHA" do + it "should return the current SHA" do + resource[:revision] = '0.5.3' + expect(provider.revision).to eq('34e6012c783a') + end + end + end + context "when given a SHA as the resource revision" do + before do + provider.expects(:hg).with('parents').returns(fixture(:hg_parents)) + end + + context "when it is the same as the current SHA", :resource => {:revision => '34e6012c783a'} do + it "should return it" do + resource[:revision] = '34e6012c783a' + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + expect(provider.revision).to eq(resource.value(:revision)) + end + end + + context "when it is not the same as the current SHA", :resource => {:revision => 'not-the-same'} do + it "should return the current SHA" do + resource[:revision] = 'not-the-same' + provider.expects(:hg).with('tags').returns(fixture(:hg_tags)) + expect(provider.revision).to eq('34e6012c783a') + end + end + end + end + + describe "setting the revision property" do + before do + @revision = '6aa99e9b3ab1' + end + it "should use 'hg update ---clean -r'" do + expects_chdir + provider.expects(:hg).with('pull') + provider.expects(:hg).with('merge') + provider.expects(:hg).with('update', '--clean', '-r', @revision) + provider.revision = @revision + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb new file mode 100644 index 00000000..e331cae6 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/p4_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:p4) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :p4, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('p4').returns('/usr/local/bin/p4') + end + + spec = { + :input => "Description: Generated by Puppet VCSrepo\nRoot: /tmp/vcsrepo\n\nView:\n", + :marshal => false + } + + describe 'creating' do + context 'with source and revision' do + it "should execute 'p4 sync' with the revision" do + resource[:source] = 'something' + resource[:revision] = '1' + ENV['P4CLIENT'] = 'client_ws1' + + provider.expects(:p4).with(['client', '-o', 'client_ws1']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source) + "@" + resource.value(:revision)]) + provider.create + end + end + + context 'without revision' do + it "should just execute 'p4 sync' without a revision" do + resource[:source] = 'something' + ENV['P4CLIENT'] = 'client_ws2' + + provider.expects(:p4).with(['client', '-o', 'client_ws2']).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.expects(:p4).with(['sync', resource.value(:source)]) + provider.create + end + end + + context "when a client and source are not given" do + it "should execute 'p4 client'" do + ENV['P4CLIENT'] = nil + + path = resource.value(:path) + host = Facter.value('hostname') + default = "puppet-" + Digest::MD5.hexdigest(path + host) + + provider.expects(:p4).with(['client', '-o', default]).returns({}) + provider.expects(:p4).with(['client', '-i'], spec) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + ENV['P4CLIENT'] = 'test_client' + + provider.expects(:p4).with(['client', '-d', '-f', 'test_client']) + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + provider.expects(:p4).with(['info'], {:marshal => false}).returns({}) + provider.expects(:p4).with(['where', resource.value(:path) + "..."], {:raise => false}).returns({}) + provider.exists? + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb new file mode 100644 index 00000000..6a37c205 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb @@ -0,0 +1,160 @@ +require 'spec_helper' + +describe Puppet::Type.type(:vcsrepo).provider(:svn) do + + let(:resource) { Puppet::Type.type(:vcsrepo).new({ + :name => 'test', + :ensure => :present, + :provider => :svn, + :path => '/tmp/vcsrepo', + })} + + let(:provider) { resource.provider } + + before :each do + Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git') + end + + describe 'creating' do + context 'with source and revision' do + it "should execute 'svn checkout' with a revision" do + resource[:source] = 'exists' + resource[:revision] = '1' + provider.expects(:svn).with('--non-interactive', 'checkout', '-r', + resource.value(:revision), + resource.value(:source), + resource.value(:path)) + provider.create + end + end + context 'with source' do + it "should just execute 'svn checkout' without a revision" do + resource[:source] = 'exists' + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context 'with fstype' do + it "should execute 'svnadmin create' with an '--fs-type' option" do + resource[:fstype] = 'ext4' + provider.expects(:svnadmin).with('create', '--fs-type', + resource.value(:fstype), + resource.value(:path)) + provider.create + end + end + context 'without fstype' do + it "should execute 'svnadmin create' without an '--fs-type' option" do + provider.expects(:svnadmin).with('create', resource.value(:path)) + provider.create + end + end + + context "with depth" do + it "should execute 'svn checkout' with a depth" do + resource[:source] = 'exists' + resource[:depth] = 'infinity' + provider.expects(:svn).with('--non-interactive', 'checkout', '--depth', 'infinity', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + + context "with trust_server_cert" do + it "should execute 'svn checkout' without a trust-server-cert" do + resource[:source] = 'exists' + resource[:trust_server_cert] = :false + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + it "should execute 'svn checkout' with a trust-server-cert" do + resource[:source] = 'exists' + resource[:trust_server_cert] = :true + provider.expects(:svn).with('--non-interactive', '--trust-server-cert', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end + end + end + + describe 'destroying' do + it "it should remove the directory" do + expects_rm_rf + provider.destroy + end + end + + describe "checking existence" do + it "should check for the directory" do + expects_directory?(true, resource.value(:path)) + expects_directory?(true, File.join(resource.value(:path), '.svn')) + provider.exists? + end + end + + describe "checking the revision property" do + before do + provider.expects(:svn).with('--non-interactive', 'info').returns(fixture(:svn_info)) + end + it "should use 'svn info'" do + expects_chdir + expect(provider.revision).to eq('4') # From 'Revision', not 'Last Changed Rev' + end + end + + describe "setting the revision property" do + before do + @revision = '30' + end + context 'with conflict' do + it "should use 'svn update'" do + resource[:conflict] = 'theirs-full' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'update', + '-r', @revision, + '--accept', resource.value(:conflict)) + provider.revision = @revision + end + end + context 'without conflict' do + it "should use 'svn update'" do + expects_chdir + provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision) + provider.revision = @revision + end + end + end + + describe "setting the revision property and repo source" do + before do + @revision = '30' + end + context 'with conflict' do + it "should use 'svn switch'" do + resource[:source] = 'an-unimportant-value' + resource[:conflict] = 'theirs-full' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'switch', + '-r', @revision, 'an-unimportant-value', + '--accept', resource.value(:conflict)) + provider.revision = @revision + end + end + context 'without conflict' do + it "should use 'svn switch'" do + resource[:source] = 'an-unimportant-value' + expects_chdir + provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value') + provider.revision = @revision + end + end + end + +end diff --git a/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/type/README.markdown b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/type/README.markdown new file mode 100644 index 00000000..1ee19ac8 --- /dev/null +++ b/tools/laptop_puppetisation/modules/vcsrepo/spec/unit/puppet/type/README.markdown @@ -0,0 +1,4 @@ +Resource Type Specs +=================== + +Define specs for your resource types in this directory. diff --git a/tools/laptop_puppetisation/site.pp b/tools/laptop_puppetisation/site.pp index 7ee9e4e1..9f7abf63 100755 --- a/tools/laptop_puppetisation/site.pp +++ b/tools/laptop_puppetisation/site.pp @@ -1,54 +1,6 @@ -# Need to determine how the user/group is declared by IT -$user = 'wilson' -$group = 'admin' - -#The following dirs need to have its user/group updated to the homebrew user pre-install -#Exec is used as this resource is also managed by the homebrew module -#smk: gildas-homebrew module needs to be updated to fix this -exec { 'share_doc_group': - path => ['/bin','/usr/sbin/','/usr/bin/'], - command => "chgrp $group /usr/local/share/doc", - before => Class['homebrew'], - unless => "ls -al /usr/local/share/doc | grep $group" -} - -exec { 'share_doc_user': - path => ['/bin','/usr/sbin/','/usr/bin/'], - command => "chown $user /usr/local/share/doc", - before => Class['homebrew'], - unless => "ls -al /usr/local/share/doc | grep $user" -} - -#Install homebrew -class {'homebrew': - user => $user, - group => $group, -} - -#Update Brew to ensure cask available -exec { 'update_brew': - require => Class['homebrew'], - command => '/usr/local/bin/brew update', - environment => ["HOME=/Users/$user"], - user => $user -} - -#Install git, tmux, gnupg using home-brew -package {['git', 'tmux', 'gnupg']: - ensure => installed, - provider => brew -} - -# smk: I'd like to do this via the homebrew package but havnt got tapping into cask repo working properly -# thekevjames-homebrew module offers this but have found this module problematic. -exec { 'install_bitbar': - require => Exec['update_brew'], - command => '/usr/local/bin/brew cask install bitbar', - creates => '/Applications/BitBar.app', - environment => ["HOME=/Users/$user"], - user => $user -} - -#Install rvm -include rvm -rvm::system_user { $user: } +include qaxcode +include qahomebrew +include qapackages +include qarubyecosystem +include qavmpoolerbitbar +include vmfloaty