From f5abddd9735f673a33c24b8815420873a7d9d973 Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Mon, 20 Apr 2015 17:25:50 +0200 Subject: [PATCH] Update puppet modules to their respective master Update apache to 8df51aafe71921181999a9f3d1845ce2d98acb8f 8df51aafe71921181999a9f3d1845ce2d98acb8f Merge pull request #1104 from mhaskel/pin_concat 98766fd6790092df829c1a5f7546c1f6c8639aff Use concat 1.2.x 28a53911fa215623ad142abf72ee63d618fce7bb Merge pull request #1101 from cmurphy/fix_access_log_tests 3c2063330d4ecfbf9c89d4b4c4e7459f476e4d8f Use string instead, not regex, for file test 2858f981c19680cc9ddc7b92fcf76199e8d42459 Merge pull request #1100 from mat1010/MODULES-1932-proxy_pass_match-fix 26b77592d86bc3f4fe9cc68277c844b000a8799d - Changed rspec test for proxy_pass_match to be more precise 355f6fa3bac98a71bde2fcd777e08ba8580a80d9 Merge pull request #1099 from mlandewers/expires_typo 7fdafeeb3bdda9c5fc4d7bb1cfaa3c236e1b40e5 - Changed vhost.pp to make use of the proxy template when proxy_pass_match is defined - Added rspec tests for proxy_pass_match b4c7ce6f9dafdd792db5bd3db0b19bf368f5e33b Fix typo in expires documentation 9202d40ebf63e3e73a2f25f7a1477651249952b2 Merge pull request #1097 from mrgum/master 09da0d12555686b7729124361143627612291220 Merge pull request #1057 from fraenki/param_lib_path b1d640ffd5d79fd7442eab2f3f4120ce73406025 make $lib_path configurable c901662a60f92632fa8eecbc478b1ef24d3f4c56 validate_apache_log_level function to apply same test to both apache class and vhost - trace levels also supported 0e8fb047fa27315b3266c596dc8ffce2901647ab Merge pull request #1095 from pmoranga/patch-1 69e0a89996f39398abe924e4cbc87c19b441ab91 Merge pull request #1070 from stevenpost/fixes/apache_name 8f8f6acf0dfefa7a7f6496404a0ce68d5c32a34f fix syntax of code examples 296aab51eb4925dcc80cb60bd2d99f51d121df99 The base class must be defined first so the parameters are known 4290182ba4b0432bcb0deae2e2ab963dd116a456 no longer enforce default value for $apache_name Change-Id: Icdc08c26b7a7da1afdbd9e79f836ef6d97847be6 Update ceilometer to e87b29e6efa1ee37bd80b49624e75ea98d123cbb e87b29e6efa1ee37bd80b49624e75ea98d123cbb Merge "Synchronize LICENSE file with OpenStack projects" fae87c07a6bc0b8b66651147405c4310ab528a74 Synchronize LICENSE file with OpenStack projects 0ec70ff60f620a1af29ae64a646ee7e5ad98ebb9 spec: Add Unit Tests for Ceilometer_config type/provider 2b3a328ea6776a74e1335c7d800763420b403916 Pin puppetlabs-concat to 1.2.1 in fixtures 1c3a3aedddcd8f923bf00763b269b1f8e643b1a1 Merge "Add udp_address/udp_port parameters for collector." 2405adff7d8b08681ed0d97ca5391be5404c5fd2 Add udp_address/udp_port parameters for collector. 90446142d9b5e1e0c21e98434e5ff0515a2782ad Fix some missing rspec3 keywords Change-Id: Id07815af4e1c390312e270dfbc43c863a059e676 Update glance to eaddd54d8ac87571a01046b5da7dbca33f3b3a59 eaddd54d8ac87571a01046b5da7dbca33f3b3a59 Merge "Synchronize LICENSE file with OpenStack projects" aa19066721a8efe5ddc545a7a9b36c8f6a65cccc Synchronize LICENSE file with OpenStack projects c0feafd0e9705870349b6b75ef1727ddd6b81035 Merge "Revert "Separate api and registry packages for Red Hat"" 876e857b29970081737e47d4a9ffe63d9776b73e Revert "Separate api and registry packages for Red Hat" 354ae692a502a6089f4f82b3b58ee2aaa42443a2 Fix os_region_name in provider 3f07c87f888e8770ca85e976688c25c0c6a90e9d Merge "Change location to be a param, not a property" 1d0a8ba83dfa0b4970b1b40259f45e3dd77ea543 Change location to be a param, not a property Change-Id: I526d33fd1a1e6c9b945522bf03188de5b36ed97d Update gluster to 4b96b871dc414727160b51a7a454c518382ea9aa 4b96b871dc414727160b51a7a454c518382ea9aa Add value for value for performance.readdir-ahead volume property. 2ecc70a439ae96b992ea0a0ff972da1b26c1a661 Update data.pp ce2b0b7638b046372e8f02a37c10d2e70f0292fb typo bfc0a1956b65ec2f0816502d2c450a1fee9879e9 Small nitpick to fix indenting. 0e3504ea279bf6f3ccf5a5c3d1877467eece1807 added mount owner and group parameters Change-Id: If2bbd155acf3fbab31c8867484dd36860aeb4272 Update gnocchi to 135849d3f11592f6e6b1d4d86ac161a265ad3d28 135849d3f11592f6e6b1d4d86ac161a265ad3d28 Use the new ':expect' syntax in rspec 3.x Change-Id: I23fc3e4c956229600143219a936b26eff5acb1ab Update haproxy to 33ceaf932fb694e54fc3d917580e2c89e40f0ae7 33ceaf932fb694e54fc3d917580e2c89e40f0ae7 Merge pull request #179 from tphoney/gentoo_135 7edeb391b8eb7c4601758449c286c85b97432b0d adding unit tests, removing official support. b9e58e4b36dcf294237aeda0ac1d10c8011fccb8 gentoo compatibility ea48e0b3279cc4df9e92cf029078f26e1dbbe095 Merge pull request #173 from antaflos/options-as-array-of-hashes d9dd15aa0a86be5635b7d13c03bf4395b22371b9 Implement `options` as array of hashes so order is preserved Change-Id: I79b9fc9337f0609cd5815200c014b4660b17fffc Update heat to 04b16b21502d43384dfd083098b40da6e943b9a5 04b16b21502d43384dfd083098b40da6e943b9a5 Merge "Synchronize LICENSE file with OpenStack projects" 94d40ed7b0e2b2aa854c286770b9ec336ddcfba7 Synchronize LICENSE file with OpenStack projects 80e16dc9758ee6307f99ad3a14d5d26d70629fcd Merge "Pin puppetlabs-concat to 1.2.1 in fixtures" bda97e32c7aea93cc225fff9826dfec25f032321 Pin puppetlabs-concat to 1.2.1 in fixtures c280fa550114744adb0b572982c0820ace9b207b Fix Keystone domain class 744f4bbcf5bfa8d09993c6e598b10c4190c10467 Create a sync_db boolean for Heat. Change-Id: If900a21068ff9d79a81a162eaf450293d6edd87d Update horizon to 78610f93b41698401af0ffb9f0f9207e7c23b17a 78610f93b41698401af0ffb9f0f9207e7c23b17a Merge "Synchronize LICENSE file with OpenStack projects" 9e3f78d693705a6e19a1aa60434f78b3263963c7 Synchronize LICENSE file with OpenStack projects 32ed597ccc069086bcb0a0e1e722638072d18fcf Pin puppetlabs-concat to 1.2.1 in fixtures cb436e722e68564acc8dd98fa1c9b32ea34a00b7 spec: updates for rspec-puppet 2.x and rspec 3.x f6bece8c53c0bc5fb690728f91aec38e92d770da Add support for Neutron DVR and L3 HA options Change-Id: I619cc0d619c595a9fbb06396158c8df8eb9815a5 Update keystone to c1f5e5159f2bae6003a535c8ce3070d8cfb7f089 c1f5e5159f2bae6003a535c8ce3070d8cfb7f089 Merge "Synchronize LICENSE file with OpenStack projects" 3c016ff6652d2edfb37ed2054ad0f3744df407bf Synchronize LICENSE file with OpenStack projects 4df19a29ee3501da527b349e456969188498c85d Merge "examples: fix apache_with_paths.pp" feacfd425186acf86237306c99d4c5a7cdbc2867 Pin puppetlabs-concat to 1.2.1 in fixtures 3f0c6d5f96d84108d03f0fec0a477cb714baca64 examples: fix apache_with_paths.pp 1a6ce2e16b329f8d735efd35270a176d6778ff86 Merge "New option replace_password for keystone_user" 6897fada5f0b51188c7a969f986859d787f7d7e4 Merge "Create a sync_db boolean for Keystone." b0b4c591bc6a59feb344db566b754f195cda6a1a Fix keystone unit tests ca7cacb2a37371b87243eb505c08bf5cd63ff275 Create a sync_db boolean for Keystone. 6cdc1731001c4d677242eef0eb670d5b57ea348a Makes distinct use of url vs auth_url 6db9a52cde33a60b5cec85e5bdee8119deca4973 New option replace_password for keystone_user Change-Id: I3b2a791b730b9c633e0b7d2f4e3591bb2d39c653 Update module-collectd to 1bd511019fe1da9b305b259862aa27516f083be6 1bd511019fe1da9b305b259862aa27516f083be6 Merge pull request #250 from simonpasquier/fix-mysql-plugin-permissions e9f42c28b99764411b83fd9975dc22c2350557c7 Fix permission on MySQL plugin file a47ffaf81cdbec568b43eeb6a8788fdc4c957cc2 Merge pull request #248 from pdxcat/fix_lint_warnings 70eb150684ce9d5446b34f38e1896179820afff8 Fix Rakefile to enforce failure on warnings d5269930320ab495302a0c39ccad9a8c66a2a669 Merge pull request #247 from TheMeier/patch-1 85b646ea72706e4ca53015b3a8fcd83c4bc2391c Add Gemfile.lock 02e530596c17ac06e0c911c4bd6293673d9a6958 Merge pull request #241 from noris-network/master 2c928c876358b7c07333580e6b3580fcd50dd478 Merge pull request #242 from txaj/readme-contributing e7a11f1aadf5dd0ab48749151453331926d4d8a2 CreateFiles/CreateFilesAsync expect boolean values 8db34e691308945aa90b7b5387b077978ff7bbee Add a section to explain version scoping & known issue for #162 859f05bf89d8c7dc06fdd3a6b5b8d2329f3cf5f9 allow to disable forwarding in network::server Change-Id: I96946e9718d10137e1530a20966fc18fb2774e87 Update mysql to 873dea342fd05821e4998c10066b99bdf25777e6 873dea342fd05821e4998c10066b99bdf25777e6 Merge pull request #699 from melan/master 6a79d2683833e87c9a8d6b21655bb268bf425f99 references to README.md and default values were added to workaround warnings from puppet-lint 97c9eea81e3f1ff8f0bd4c4687331401a9a8cad6 Merge pull request #698 from mhaskel/MODULES-1928 298242e043a9c90c3365f45c5613ffb1d9378831 MODULES-1928 - allow log-error to be undef eb3fa4e9f511e608718fb43de5093f290d8ffe00 Merge pull request #697 from fraenki/freebsd_support c2ec74b1b5bf2b01dd7e8067896bf1435d4336ad Merge pull request #687 from igalic/provider-regr a2faed23ac62cdd465e941dd7bfcdca4443afc71 fix FreeBSD support for backups 1c3bf95e21e91e89fd64688e7df07ff8ea4a21e7 mysql backup: fix regression in mysql_user call Change-Id: I41b72f1f7f02b5f96c18a11725a5040121bc117e Update nova to 7f40c612d2fc25b9ceb91899c2c634e5e05ee3b9 7f40c612d2fc25b9ceb91899c2c634e5e05ee3b9 Pin puppetlabs-concat to 1.2.1 in fixtures 9271c137859a797d46939fb30d7684a11401acb5 Merge "Move rabbit/kombu settings to oslo_messaging_rabbit section" ce1033f87176c789dac8e3cbaa99f4940edd0981 Merge "Add rspec coverage output" 2eda7208c4784043038bcdb316f0fbe0c76cd415 Merge "Adds OracleLinux support" 2f0f6659306262863c2d6abc5a64d268322f2354 Merge "move setting of novncproxy_base_url" a5dcd4d34c22c51685ca54ca17f0f1c4695d1373 Add rspec coverage output 5d3c3c63efea1fb30dc9e1334ee8866025a68d1a Adds OracleLinux support a8ba5a41cdbcbc5b4123cc97e0e46f4c7702b8fa Allow libvirt secret key setting from param 96eafbd792e2ceaa5ee972e85337fc1ff7d1f008 Move rabbit/kombu settings to oslo_messaging_rabbit section 28268ad9c74370b193efe8e972c808d76bb8c8d7 move setting of novncproxy_base_url Change-Id: I3c6fb08e5d6671c5373fde91e6a575de73358a9c Update ntp to 060c453a9bbd87d1bf229db70ee6367033a2910e 060c453a9bbd87d1bf229db70ee6367033a2910e Merge pull request #260 from tphoney/leapfile_fix 7d30e162eedd3a1aba3f505736d460dc96c09ae7 fixing the tinker / panic unit tests b6bb239fa9a98414890598fdba327c7bccf8be11 Added leapfile parameter d6540684e64078fb0ccbf38e26dc380d64747896 Merge pull request #258 from mhaskel/update_stdlib_version 8f52991230a1954ada7663ccad81ac52ccc57210 Added dependency on stdlib 4.6.0 4412b3e77c555c3da5af5a971dd168038e3785d6 Merge pull request #257 from mhaskel/update_metadata 430ce7ad1286adb804200fe5ad8359d6fe4a77e0 PR #255 added a dependency on stdlib >= 4.6.0 da5d844a932f756583ccda8c7b9aead7e27ba386 Merge pull request #255 from sorrowless/add_couple_options 75d47b432ba4fe788b36729740aa9eed21350913 Add tinker, stepout and poll options, change panic option 03d8b2c06134fc710e3dc68ed0bcac797854e6df Merge pull request #254 from juniorsysadmin/udlc-stratum bbf6635dea2bbf204800b5aea10c298ef52df768 (MODULES-1837) Make udlc stratum configurable 789d47a0c2b52f874dc63569e1e59aca447cba75 Merge pull request #253 from mhaskel/MODULES-1836 e2f7aa904e54ed07f76d4ab7268f39816ff88ec4 Add tests for the peers parameter 0b3eac9bac617189864b1e37c050b2b1ab33657e MODULES-1836 - Added support for peers Change-Id: I83c769cbfa354f1771419a1f3278ba24839059f8 Update openstack_extras to d4af0036a42c2deebcef1aa690101aa35aec930d d4af0036a42c2deebcef1aa690101aa35aec930d Merge "Synchronize LICENSE file with OpenStack projects" f0c73a62a600ba8ea43bebd6d4d547b480a4913c Synchronize LICENSE file with OpenStack projects Change-Id: I721b1e1526c54ed07c34ed278ba9531be0122627 Update openstacklib to 581d1ee95eb3d9d928558dcd932512058ddb0082 581d1ee95eb3d9d928558dcd932512058ddb0082 Merge "Synchronize LICENSE file with OpenStack projects" 59accf61cab24b3ef6f85384c37bec3de9bd4b2d Synchronize LICENSE file with OpenStack projects 9ddc6332c566541e03d21819dc7b0b240cc62308 Merge "wsgi/apache: fix wsgi_process_group doc" 423707b0f944ba052bb86a1cc23e5866a3640376 Unpin rabbitmq module 8c1d56546ef41bf62c993cc96589f8052f81c737 Pin puppetlabs-concat to 1.2.1 in fixtures 11d033131e4cedfb42967730e2a761f0aaa75886 Correct wsgi_daemon_process_options key 331b89a4d9f49e3bc3ed84a17688e0b0800855e7 Merge "Targeting Keystone V3 API support" a68fed0de25d75e462a4c355aa791de3f30082db wsgi/apache: fix wsgi_process_group doc d4073c27216a9432d9df312997be5fad91b4c0f5 Targeting Keystone V3 API support Change-Id: If2d7ad37c74620a0a7c3bd653cff9cacd82e6dba Update rabbitmq to 2c3fd7ea004272257b8efaa098cd2ea18b2b7751 2c3fd7ea004272257b8efaa098cd2ea18b2b7751 Merge pull request #337 from fcharlier/limits_redhat a46fb0cd886f0aa1dea16fd96115091596eb5541 Add file_limit support for RedHat platforms 1a7859c26795b9ba6ff1bd51f7b729bc826a8544 Merge pull request #323 from jaxim/fix/master/MODULES-1856 87b665bdd5e49c46ee6131b9873dd623cc863908 Merge pull request #338 from scarby/master 27740db5a24341e735fef03e5000a6a9ef3ddaa4 fixed type error rabbitmq_plugin does not have provider f45bbcc7386a4f2ee6a48f7a48a1a1e0da1c7190 Merge pull request #332 from tamaskozak/master 8bbfe320035fae2ae900211501008d63dc3c171c Fix check_password function and use the standard rabbitmq api call instead 01aae16bd109cda2d77f28f1843df7e766186008 MODULES-1856 - Fix to allow bindings and queues to be created on non-default management port Change-Id: I0f286f3d97b6cbd6853cc06b1523afa0f5cfc222 Update rsync to f8081918a503a7301772c93373eb70b90d399538 f8081918a503a7301772c93373eb70b90d399538 Merge pull request #65 from mhaskel/add_tests_for_61 b80d86a9f6f88354dca9f931740608e1d05f9589 Test and make sure the service name is set correctly for SuSE d80dbb59194c4c97939f78b320c0208d6f474a74 Update server.pp to work with SUSE OSs c6ad435e8faf6a501f1815a92d7bb2deea384f77 Merge pull request #64 from juniorsysadmin/fix-stdlib-dep 0235c98d1fc08b3e10670f1f66bf58e4b6e7635b Fix stdlib dependency version Change-Id: If7b8f46dffc8ed975d6750ca52232de1ed5142bd Update sahara to 826a2c8480074ce20f93c983721d10d95f2c9d76 826a2c8480074ce20f93c983721d10d95f2c9d76 Synchronize LICENSE file with OpenStack projects cde7ccb124403195c5ad12edf99d36b8b59da8ea Pin puppetlabs-concat to 1.2.1 in fixtures 7dfdc87303f40bddd2fc72c974fbddb3d16f04d0 Makes kombu_ssl_* parameters optional when rabbit_use_ssl => true Change-Id: I142ef551d9af629bdf5fcd5e45693749fdc7f35a Update stdlib to 2a8d7acd7e8ce84826cb8293308721fe7b4095ea 2a8d7acd7e8ce84826cb8293308721fe7b4095ea Merge pull request #440 from DavidS/fix-error-message c27513463d9b0a59cda1287273621fc4e158a486 fqdn_rand_string: fix argument error message 2c6cff6f7224f2e8b90b6f0107cd9e46362aa306 Merge pull request #439 from puppetlabs/4.6.x 8a1d1e2f3425ff8fa1d7e74463ec226df2b968c8 Merge pull request #314 from amateo/feature/loadyaml_check_file 73474b00b5ae3cbccec6cd0711311d6450139e51 Merge pull request #438 from hunner/fix_date ba4033ed253507a922ae7a927cd70d3967d34b98 Fix the 4.6.0 release date 4c90e4df52b4e9ab10eeec7ad18b851db6f8959e Merge pull request #437 from hunner/release_4.6.0 5382ca0176f9638aa9acdfc22cf68ba233b77f57 Prep for 4.6.0 ac24e7acc767bce9cc1977f90c798df94292813e test case for when the file does not exist 59b3fb4472c6ceafc6762739e767294054787bd4 Merge pull request #434 from bmjen/modules-2474 601e2e2574c37f5496323ed56702d4a657c278dd Modules-2474: Only runs enhanced salts functional test on systems that support it. cf7dbef1e8ac3b3c25398f4d985530113148e03f Merge pull request #433 from cmurphy/fix_acceptance 65116dafd507c5111044853861f9b10b02c91854 Fix acceptance tests for #405 afec0ab9813524d894969f0b113d02bbe378289c Merge pull request #425 from jeffcoat/validate_augeas_spec 5ee6e960f69fbee3ca53496c4437f98784aeb738 Merge pull request #431 from bmjen/file-line-refactor acf57bbe31f9b51792965b47cda6774d3bd59999 Merge pull request #432 from cmurphy/fix_acceptance_undefined_var e43f0582960707f8a7ff9f087ca2b521c1797a91 Fix unsupported platforms variable name in tests 0af0d7e5392a69f0ed72fa1b0225fe2a61188319 Add spec tests and pulled in PR #427 Changed append line to open in 'w' mode and have to rewrite lines in order to append new line 35303ce0f7cf66feb7499d9671a7d2121a0f52b1 file_line honors after if match not found. f2fa4fbd62b1cd10a25a19d7a8c4729b189e6312 Merge pull request #430 from mhaskel/gjngeldenhuis-docupdate ee2225b63c4356dafffedc16ec0376af58d42dad Clarifying behaviour of attributes and adding an extra example. 8fba5c058ba344421796cceca8f96dffcba0a4fc Merge pull request #405 from elyscape/feature/fqdn_rand_strings 487e8d4cd7384e9c3170f93a71f14c0a78766a3f Merge pull request #408 from elyscape/feature/pw_hash 5ecfe2f67640c33be0efb97ccd727001a43bbbb4 Merge pull request #429 from DavidS/modulesync-configs-update 9a1fee6c682717b20ab5c287a47ae46ab06b8e11 Update Travis CI job from current modulesync_configs 23be4020ddd4f95dc589ecebe57cd1b27d85248b (MODULES-1737) Add pw_hash() function a82266c256784c4af229e026b00a4dcf9e779270 (MODULES-1715) Add fqdn_rand string generators 3fec51ac65725ee10710030953a6d6b206de931d Fix off-by-one error in validate_augeas_spec.rb that was causing rspec failure. b9560df899fdea34ac69692ef2447ffdd2d3365a Check if file exists before loading with loadyaml. If not, return nil Change-Id: I24f5db84d7db3e8d7bf45d47bdac34eb4f0a7fdb Update swift to 35b386479d20853802bec55bc38521d2894e762e 35b386479d20853802bec55bc38521d2894e762e Merge "Synchronize LICENSE file with OpenStack projects" 56f1eb501485fef3c793fdfb6118608b142ec3ee Synchronize LICENSE file with OpenStack projects f67877f1fa2dbb33702f61cee3c9df76ba541181 Merge "read_affinity requires affinity sorting_method" 2737af141ac88a07cda39e402dacb4275792aa8f Pin puppetlabs-concat to 1.2.1 in fixtures cb6aa56b545f0d47a8a89bcd4c903de2ddb21826 Merge "Fix ipv6 support" ebb898656777444677584683cc8a0d2ac430eded Merge "Tag all Swift packages" 6dc85b0f7918fa295974f7afbb1a6b8a26f8f953 Notify services if swift.conf is modified e04486fe46452978839b1c11a67d7fee59697106 read_affinity requires affinity sorting_method 06addb7b3b58289ae785c5bedc10682f3d959c3a Fix Rspec 3.x new is_expected.[to|to_not] keywords 9561ffffa21db52eca95e5682f0bbe6364994fdf Tag all Swift packages b6ba9f09b291252a196d69c3e30b188fe77c2c4a Fix ipv6 support 7ad2a10e1fd5f78a6632cf76c8def3ae4559677e Update ssh module version Change-Id: I071d68360b2c7f7a7d6b66de8a1c11406ffd67a4 Update tempest to 7048e67794617ac5ebf7cdd5baadd0d240386695 7048e67794617ac5ebf7cdd5baadd0d240386695 Merge "Synchronize LICENSE file with OpenStack projects" 7e072e854544a2bfff3b58014d4e50565aa6a243 Synchronize LICENSE file with OpenStack projects 301f58f60317a816572596fce1f0093ad4f8e8e0 Add rspec coverage output Change-Id: I3d63c5ddb8bcc0d177c4dc79ff5538cd4ba8f8cb Update tripleo to e0921709d946d8db95f2a399a1b9da93d6b73d06 e0921709d946d8db95f2a399a1b9da93d6b73d06 Merge "Loadbalancer: Add support for Redis" 3bef84147bd7df52e8303bcb5481ce5d3351f997 Loadbalancer: Add support for Redis 72e8834efa188ecef879e5ae3141428b6a88f0a5 Rethink the backup option for Galera Change-Id: Ied24067690dc42f2862782dc0c2756a9249499a5 Update vcsrepo to 210ca5acd8eecc909eae248745e24f0debd66ffc 210ca5acd8eecc909eae248745e24f0debd66ffc Merge pull request #243 from rnelson0/quotes c858962ef98782f261043c4d5d6dd2ab182afaec Enforce the style guide's recommendation of single quotes as the default. Change-Id: If6d75d81c9106cfedfafee6c942847c746f0712f Update vswitch to 5079b23938aa2d98dea86e89c05194fd3deb3a29 5079b23938aa2d98dea86e89c05194fd3deb3a29 Add puppet-lint-param-docs plugin e895b0d641e8e1e519f4087e58a77550b13ad86d spec: updates for rspec-puppet 2.x and rspec 3.x da6eaa1d3ad0adea95efc9c3fc6b63423feb4b29 Add Puppet 4.x lint checks 7d83f160ccae89c8cd6ffded4a37ebcf39b13798 Fix metadata.json lint issues Change-Id: I641c00add5f13c600659aa883fa971f73e07969a Update xinetd to 4f16fc824e04d724a486634bd9c26ef549f10ff5 4f16fc824e04d724a486634bd9c26ef549f10ff5 Merge pull request #56 from mhaskel/rebase_31 b23fe88578ffb5f44b1cb1b59bd079479e3bcb31 Removed default vaules from xinetd.conf and added params for each Change-Id: I448195bfc632f5f1193d737f2d4f2e5dd3e10e80 --- Puppetfile | 50 ++-- apache/.fixtures.yml | 4 +- apache/README.md | 22 +- .../functions/validate_apache_log_level.rb | 27 ++ apache/manifests/dev.pp | 3 - apache/manifests/init.pp | 6 +- apache/manifests/mod.pp | 2 +- apache/manifests/mod/expires.pp | 6 +- apache/manifests/mod/wsgi.pp | 2 +- apache/manifests/mpm.pp | 2 +- apache/manifests/package.pp | 10 +- apache/manifests/vhost.pp | 8 +- apache/spec/acceptance/vhost_spec.rb | 68 +++++ apache/spec/classes/dev_spec.rb | 29 ++- apache/spec/classes/mod/dev_spec.rb | 20 +- .../functions/validate_apache_log_level.rb | 39 +++ ceilometer/.fixtures.yml | 5 +- ceilometer/LICENSE | 181 +------------- ceilometer/manifests/collector.pp | 22 ++ .../classes/ceilometer_agent_polling_spec.rb | 24 +- .../spec/classes/ceilometer_api_spec.rb | 20 +- .../spec/classes/ceilometer_collector_spec.rb | 39 ++- .../ceilometer_config/ini_setting_spec.rb | 42 ++++ .../spec/unit/type/ceilometer_config_spec.rb | 53 ++++ glance/LICENSE | 208 +--------------- glance/lib/puppet/provider/glance.rb | 8 +- .../puppet/provider/glance_image/glance.rb | 4 - glance/lib/puppet/type/glance_image.rb | 2 +- glance/manifests/api.pp | 18 +- glance/manifests/init.pp | 19 +- glance/manifests/params.pp | 4 +- glance/manifests/registry.pp | 18 +- glance/spec/classes/glance_api_spec.rb | 14 +- .../spec/classes/glance_cache_cleaner_spec.rb | 2 +- .../spec/classes/glance_cache_pruner_spec.rb | 2 +- glance/spec/classes/glance_registry_spec.rb | 13 +- glance/spec/classes/glance_spec.rb | 4 +- glance/spec/unit/provider/glance_spec.rb | 2 +- gluster/manifests/brick.pp | 2 +- gluster/manifests/mount.pp | 10 + gluster/manifests/volume/property/data.pp | 5 +- .../gnocchi_config/ini_setting_spec.rb | 8 +- gnocchi/spec/unit/type/gnocchi_config_spec.rb | 8 +- haproxy/.gitignore | 1 + haproxy/README.md | 47 +++- haproxy/manifests/install.pp | 10 + haproxy/manifests/params.pp | 2 +- haproxy/spec/classes/haproxy_spec.rb | 10 +- haproxy/spec/defines/frontend_spec.rb | 27 ++ haproxy/spec/defines/listen_spec.rb | 27 ++ haproxy/templates/fragments/_options.erb | 14 ++ heat/.fixtures.yml | 4 +- heat/LICENSE | 181 +------------- heat/manifests/api.pp | 2 +- heat/manifests/api_cfn.pp | 2 +- heat/manifests/api_cloudwatch.pp | 2 +- heat/manifests/engine.pp | 5 +- heat/manifests/init.pp | 22 +- heat/manifests/keystone/domain.pp | 1 + heat/spec/classes/heat_api_cfn_spec.rb | 11 + heat/spec/classes/heat_api_cloudwatch_spec.rb | 11 + heat/spec/classes/heat_api_spec.rb | 10 + heat/spec/classes/heat_engine_spec.rb | 15 ++ .../spec/classes/heat_keystone_domain_spec.rb | 1 + horizon/.fixtures.yml | 4 +- horizon/Gemfile | 4 +- horizon/LICENSE | 4 +- horizon/manifests/init.pp | 19 +- horizon/spec/classes/horizon_init_spec.rb | 47 ++-- .../spec/classes/horizon_wsgi_apache_spec.rb | 38 +-- horizon/spec/shared_examples.rb | 2 +- horizon/spec/spec_helper.rb | 2 +- .../parser/functions/os_any2array_spec.rb | 20 +- horizon/templates/local_settings.py.erb | 2 + keystone/.fixtures.yml | 4 +- keystone/LICENSE | 6 +- keystone/examples/apache_with_paths.pp | 4 +- keystone/lib/puppet/provider/keystone.rb | 6 +- .../provider/keystone_user/openstack.rb | 10 + keystone/lib/puppet/type/keystone_user.rb | 8 + keystone/manifests/init.pp | 7 +- keystone/spec/classes/keystone_spec.rb | 11 + .../keystone_endpoint/openstack_spec.rb | 22 +- .../provider/keystone_role/openstack_spec.rb | 22 +- .../keystone_service/openstack_spec.rb | 22 +- .../keystone_tenant/openstack_spec.rb | 22 +- .../provider/keystone_user/openstack_spec.rb | 102 +++++--- .../keystone_user_role/openstack_spec.rb | 26 +- module-collectd/.gitignore | 1 - module-collectd/Gemfile.lock | 232 ++++++++++++++++++ module-collectd/README.md | 14 ++ module-collectd/Rakefile | 2 +- module-collectd/manifests/plugin/curl_json.pp | 1 + module-collectd/manifests/plugin/exec.pp | 2 +- .../manifests/plugin/genericjmx/connection.pp | 4 +- .../manifests/plugin/genericjmx/mbean.pp | 2 +- module-collectd/manifests/plugin/mysql.pp | 1 + .../manifests/plugin/mysql/database.pp | 2 +- .../manifests/plugin/network/server.pp | 1 + module-collectd/manifests/plugin/ping.pp | 1 + module-collectd/manifests/plugin/snmp/data.pp | 6 +- module-collectd/manifests/plugin/snmp/host.pp | 2 +- .../templates/plugin/network/server.conf.erb | 3 + .../templates/plugin/rrdcached.conf.erb | 4 +- module-collectd/tests/plugins/iptables.pp | 2 +- module-collectd/tests/plugins/mysql.pp | 8 +- module-collectd/tests/plugins/perl.pp | 20 +- module-collectd/tests/purge_config.pp | 6 +- mysql/manifests/backup/mysqlbackup.pp | 31 ++- mysql/manifests/backup/mysqldump.pp | 33 ++- mysql/manifests/backup/xtrabackup.pp | 33 ++- mysql/manifests/client/install.pp | 1 + mysql/manifests/server/account_security.pp | 1 + mysql/manifests/server/monitor.pp | 6 +- mysql/manifests/server/service.pp | 10 +- mysql/spec/acceptance/mysql_server_spec.rb | 13 + mysql/templates/mysqlbackup.sh.erb | 6 + nova/.fixtures.yml | 4 +- nova/manifests/compute.pp | 10 +- nova/manifests/compute/rbd.pp | 15 +- nova/manifests/init.pp | 46 ++-- nova/manifests/params.pp | 2 +- nova/manifests/vncproxy.pp | 25 +- nova/manifests/vncproxy/common.pp | 54 ++++ nova/spec/classes/nova_compute_rbd_spec.rb | 15 ++ nova/spec/classes/nova_init_spec.rb | 98 ++++---- nova/spec/classes/nova_vnc_proxy_spec.rb | 1 + nova/spec/spec_helper.rb | 2 + ntp/.gitignore | 1 + ntp/README.markdown | 30 ++- ntp/manifests/init.pp | 17 +- ntp/manifests/params.pp | 39 ++- ntp/metadata.json | 2 +- ntp/spec/acceptance/ntp_parameters_spec.rb | 28 ++- ntp/spec/classes/ntp_spec.rb | 211 +++++++++++++++- ntp/spec/spec_helper_acceptance.rb | 2 +- ntp/templates/ntp.conf.erb | 32 ++- openstack_extras/LICENSE | 208 +--------------- openstacklib/.fixtures.yml | 8 +- openstacklib/LICENSE | 208 +--------------- openstacklib/lib/puppet/provider/openstack.rb | 36 +-- openstacklib/lib/puppet/util/openstack.rb | 41 +++- openstacklib/manifests/wsgi/apache.pp | 4 +- .../defines/openstacklib_wsgi_apache_spec.rb | 28 ++- .../spec/unit/provider/openstack_spec.rb | 72 ++++-- rabbitmq/README.md | 3 +- .../rabbitmq_binding/rabbitmqadmin.rb | 4 +- .../provider/rabbitmq_queue/rabbitmqadmin.rb | 4 +- .../provider/rabbitmq_user/rabbitmqctl.rb | 4 +- rabbitmq/manifests/config.pp | 50 +++- rabbitmq/manifests/init.pp | 21 +- rabbitmq/spec/acceptance/queue_spec.rb | 157 ++++++++++++ rabbitmq/spec/classes/rabbitmq_spec.rb | 138 +++++++++++ .../rabbitmq_binding/rabbitmqadmin_spec.rb | 6 +- .../rabbitmq_queue/rabbitmqadmin_spec.rb | 6 +- rabbitmq/templates/limits.conf | 2 + .../rabbitmq-server.service.d/limits.conf | 2 + rsync/manifests/server.pp | 7 +- rsync/metadata.json | 2 +- rsync/spec/classes/server_spec.rb | 15 ++ sahara/.fixtures.yml | 4 +- sahara/LICENSE | 183 +------------- sahara/manifests/notify/rabbitmq.pp | 43 ++-- .../classes/sahara_notify_rabbitmq_spec.rb | 12 + stdlib/.travis.yml | 14 +- stdlib/CHANGELOG.md | 31 ++- stdlib/README.markdown | 35 +++ .../parser/functions/fqdn_rand_string.rb | 34 +++ .../lib/puppet/parser/functions/loadyaml.rb | 7 +- stdlib/lib/puppet/parser/functions/pw_hash.rb | 56 +++++ stdlib/lib/puppet/provider/file_line/ruby.rb | 14 +- stdlib/lib/puppet/type/file_line.rb | 30 ++- stdlib/metadata.json | 2 +- .../spec/acceptance/fqdn_rand_string_spec.rb | 60 +++++ stdlib/spec/acceptance/pw_hash_spec.rb | 34 +++ .../spec/functions/fqdn_rand_string_spec.rb | 91 +++++++ stdlib/spec/functions/loadyaml_spec.rb | 6 + stdlib/spec/functions/pw_hash_spec.rb | 96 ++++++++ stdlib/spec/functions/validate_augeas_spec.rb | 4 +- .../puppet/provider/file_line/ruby_spec.rb | 88 +++++-- swift/.fixtures.yml | 8 +- swift/LICENSE | 6 +- .../lib/puppet/provider/swift_ring_builder.rb | 17 +- swift/lib/puppet/type/ring_account_device.rb | 14 +- .../lib/puppet/type/ring_container_device.rb | 14 +- swift/lib/puppet/type/ring_object_device.rb | 14 +- swift/manifests/client.pp | 1 + swift/manifests/init.pp | 1 + swift/manifests/proxy.pp | 3 + swift/manifests/proxy/swift3.pp | 1 + swift/manifests/storage/account.pp | 4 + swift/manifests/storage/container.pp | 5 + swift/manifests/storage/generic.pp | 2 + swift/manifests/storage/object.pp | 4 + swift/metadata.json | 2 +- swift/spec/classes/swift_client_spec.rb | 51 +++- .../spec/classes/swift_keystone_auth_spec.rb | 12 +- .../defines/swift_storage_generic_spec.rb | 5 +- .../puppet/type/ring_account_device_spec.rb | 7 +- .../puppet/type/ring_container_device_spec.rb | 9 +- .../puppet/type/ring_object_device_spec.rb | 9 +- swift/templates/proxy-server.conf.erb | 1 + tempest/LICENSE | 13 + tempest/spec/classes/tempest_spec.rb | 35 ++- tempest/spec/spec_helper.rb | 2 + tripleo/manifests/loadbalancer.pp | 54 +++- tripleo/manifests/redis_notification.pp | 38 +++ .../redis/redis-notifications.sh.erb | 30 +++ vcsrepo/README.markdown | 108 ++++---- vswitch/Gemfile | 18 +- vswitch/manifests/init.pp | 2 +- vswitch/manifests/ovs.pp | 32 +-- vswitch/metadata.json | 2 +- vswitch/spec/classes/vswitch_ovs_spec.rb | 4 +- xinetd/.travis.yml | 2 +- xinetd/Gemfile | 5 +- xinetd/README.md | 25 ++ xinetd/Rakefile | 5 +- xinetd/manifests/init.pp | 22 +- xinetd/manifests/service.pp | 3 +- xinetd/spec/classes/xinetd_init_spec.rb | 99 +++++++- xinetd/templates/service.erb | 3 + xinetd/templates/xinetd.conf.erb | 88 +++++-- 223 files changed, 3578 insertions(+), 2008 deletions(-) create mode 100644 apache/lib/puppet/parser/functions/validate_apache_log_level.rb create mode 100644 apache/spec/unit/puppet/parser/functions/validate_apache_log_level.rb create mode 100644 ceilometer/spec/unit/provider/ceilometer_config/ini_setting_spec.rb create mode 100644 ceilometer/spec/unit/type/ceilometer_config_spec.rb create mode 100644 module-collectd/Gemfile.lock create mode 100644 nova/manifests/vncproxy/common.pp create mode 100644 rabbitmq/spec/acceptance/queue_spec.rb create mode 100644 rabbitmq/templates/limits.conf create mode 100644 rabbitmq/templates/rabbitmq-server.service.d/limits.conf create mode 100644 stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb create mode 100644 stdlib/lib/puppet/parser/functions/pw_hash.rb create mode 100644 stdlib/spec/acceptance/fqdn_rand_string_spec.rb create mode 100644 stdlib/spec/acceptance/pw_hash_spec.rb create mode 100644 stdlib/spec/functions/fqdn_rand_string_spec.rb create mode 100644 stdlib/spec/functions/pw_hash_spec.rb create mode 100644 tempest/LICENSE create mode 100644 tripleo/manifests/redis_notification.pp create mode 100644 tripleo/templates/redis/redis-notifications.sh.erb diff --git a/Puppetfile b/Puppetfile index 0623343ad..9a46af567 100644 --- a/Puppetfile +++ b/Puppetfile @@ -1,5 +1,5 @@ mod 'apache', - :commit => 'dc26c77d8890af0df5063b021b52cd91eddaca56', + :commit => '8df51aafe71921181999a9f3d1845ce2d98acb8f', :git => 'https://github.com/puppetlabs/puppetlabs-apache.git' mod 'aviator', @@ -7,7 +7,7 @@ mod 'aviator', :git => 'https://github.com/aimonb/puppet_aviator.git' mod 'ceilometer', - :commit => '8d17c36818d99231a64d20f50ea708d59306fe22', + :commit => 'e87b29e6efa1ee37bd80b49624e75ea98d123cbb', :git => 'https://github.com/stackforge/puppet-ceilometer.git' mod 'certmonger', @@ -35,27 +35,27 @@ mod 'galera', :git => 'https://github.com/redhat-openstack/puppet-galera.git' mod 'glance', - :commit => '9c1b0a90d93913548dbada13076cac1470cc5993', + :commit => 'eaddd54d8ac87571a01046b5da7dbca33f3b3a59', :git => 'https://github.com/stackforge/puppet-glance.git' mod 'gluster', - :commit => '467620e575b8b8fb42d1980f97ae1b5863641483', + :commit => '4b96b871dc414727160b51a7a454c518382ea9aa', :git => 'https://github.com/purpleidea/puppet-gluster.git' mod 'gnocchi', - :commit => '4438badb1499ceed11b32287f861de2ce5961122', + :commit => '135849d3f11592f6e6b1d4d86ac161a265ad3d28', :git => 'https://github.com/stackforge/puppet-gnocchi.git' mod 'haproxy', - :commit => '957437013add0c92d6ff934de942867e304036f0', + :commit => '33ceaf932fb694e54fc3d917580e2c89e40f0ae7', :git => 'https://github.com/puppetlabs/puppetlabs-haproxy.git' mod 'heat', - :commit => 'bbeb24c51aa3573300a74fbcaf80d8fce3e2b8f7', + :commit => '04b16b21502d43384dfd083098b40da6e943b9a5', :git => 'https://github.com/stackforge/puppet-heat.git' mod 'horizon', - :commit => '4155185fef6d566246796d448c9e1c2557f4481c', + :commit => '78610f93b41698401af0ffb9f0f9207e7c23b17a', :git => 'https://github.com/stackforge/puppet-horizon.git' mod 'inifile', @@ -71,7 +71,7 @@ mod 'ironic', :git => 'https://github.com/stackforge/puppet-ironic.git' mod 'keystone', - :commit => '4f684b24dbd8a089bd542f2767ab56ba2aea6654', + :commit => 'c1f5e5159f2bae6003a535c8ce3070d8cfb7f089', :git => 'https://github.com/stackforge/puppet-keystone.git' mod 'manila', @@ -83,7 +83,7 @@ mod 'memcached', :git => 'https://github.com/saz/puppet-memcached.git' mod 'module-collectd', - :commit => '91e1dafad3182e64979dfeba1633f0b32bcc0649', + :commit => '1bd511019fe1da9b305b259862aa27516f083be6', :git => 'https://github.com/pdxcat/puppet-module-collectd.git' mod 'module-data', @@ -95,7 +95,7 @@ mod 'mongodb', :git => 'https://github.com/puppetlabs/puppetlabs-mongodb.git' mod 'mysql', - :commit => '5de035c60d899df305e1f3e30267726895d055da', + :commit => '873dea342fd05821e4998c10066b99bdf25777e6', :git => 'https://github.com/puppetlabs/puppetlabs-mysql.git' mod 'n1k_vsm', @@ -111,7 +111,7 @@ mod 'neutron', :git => 'https://github.com/stackforge/puppet-neutron.git' mod 'nova', - :commit => 'c191303e6b368f0124e27b6545595a69fd188662', + :commit => '7f40c612d2fc25b9ceb91899c2c634e5e05ee3b9', :git => 'https://github.com/stackforge/puppet-nova.git' mod 'nssdb', @@ -119,15 +119,15 @@ mod 'nssdb', :git => 'https://github.com/rcritten/puppet-nssdb.git' mod 'ntp', - :commit => '286acbacdb9aaa3f1255d7486078730e380195f4', + :commit => '060c453a9bbd87d1bf229db70ee6367033a2910e', :git => 'https://github.com/puppetlabs/puppetlabs-ntp' mod 'openstack_extras', - :commit => 'c9621fb6c08aa8621661ae6c88a25de6a4142e71', + :commit => 'd4af0036a42c2deebcef1aa690101aa35aec930d', :git => 'https://github.com/stackforge/puppet-openstack_extras.git' mod 'openstacklib', - :commit => 'e76240c180f969fda194f295496421cbc1e4352a', + :commit => '581d1ee95eb3d9d928558dcd932512058ddb0082', :git => 'https://github.com/stackforge/puppet-openstacklib.git' mod 'pacemaker', @@ -143,7 +143,7 @@ mod 'qpid', :git => 'https://github.com/dprince/puppet-qpid' mod 'rabbitmq', - :commit => '7dd5c7420f823babe3baf88bec67c8e43760d00e', + :commit => '2c3fd7ea004272257b8efaa098cd2ea18b2b7751', :git => 'https://github.com/puppetlabs/puppetlabs-rabbitmq.git' mod 'redis', @@ -155,11 +155,11 @@ mod 'remote', :git => 'https://github.com/paramite/puppet-remote.git' mod 'rsync', - :commit => '699650bf7e7339e1653f83143637595a0029aa51', + :commit => 'f8081918a503a7301772c93373eb70b90d399538', :git => 'https://github.com/puppetlabs/puppetlabs-rsync.git' mod 'sahara', - :commit => '303e514db06b34db1ab26e84edbbdf91d98d6679', + :commit => '826a2c8480074ce20f93c983721d10d95f2c9d76', :git => 'https://github.com/stackforge/puppet-sahara.git' mod 'ssh', @@ -171,11 +171,11 @@ mod 'staging', :git => 'https://github.com/nanliu/puppet-staging.git' mod 'stdlib', - :commit => '14a02ea21e14111071a921e82cdf3cd1f518c7f3', + :commit => '2a8d7acd7e8ce84826cb8293308721fe7b4095ea', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git' mod 'swift', - :commit => '96ad9dd2237d9d9165025fd76e3c4b7f348ea2f1', + :commit => '35b386479d20853802bec55bc38521d2894e762e', :git => 'https://github.com/stackforge/puppet-swift.git' mod 'sysctl', @@ -183,7 +183,7 @@ mod 'sysctl', :git => 'https://github.com/puppetlabs/puppetlabs-sysctl.git' mod 'tempest', - :commit => '098c4b855e5a6da843bae057d56afd89b171894f', + :commit => '7048e67794617ac5ebf7cdd5baadd0d240386695', :git => 'https://github.com/stackforge/puppet-tempest.git' mod 'timezone', @@ -191,7 +191,7 @@ mod 'timezone', :git => 'https://github.com/saz/puppet-timezone.git' mod 'tripleo', - :commit => '6f5c208f8df4df034637acd1b5fd6f4b71012d8a', + :commit => 'e0921709d946d8db95f2a399a1b9da93d6b73d06', :git => 'https://github.com/stackforge/puppet-tripleo.git' mod 'trove', @@ -199,7 +199,7 @@ mod 'trove', :git => 'https://github.com/stackforge/puppet-trove' mod 'vcsrepo', - :commit => '3d4547646d49295c91bb002fa885e187c2d89feb', + :commit => '210ca5acd8eecc909eae248745e24f0debd66ffc', :git => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git' mod 'vlan', @@ -207,10 +207,10 @@ mod 'vlan', :git => 'https://github.com/derekhiggins/puppet-vlan.git' mod 'vswitch', - :commit => '331726326a275da158a62cafdd49fb961a71d3e2', + :commit => '5079b23938aa2d98dea86e89c05194fd3deb3a29', :git => 'https://github.com/stackforge/puppet-vswitch.git' mod 'xinetd', - :commit => '5e31388979e8f3a667899fad5cefa95289e22281', + :commit => '4f16fc824e04d724a486634bd9c26ef549f10ff5', :git => 'https://github.com/puppetlabs/puppetlabs-xinetd.git' diff --git a/apache/.fixtures.yml b/apache/.fixtures.yml index 6eddf260f..4645a757f 100644 --- a/apache/.fixtures.yml +++ b/apache/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git" - concat: "git://github.com/puppetlabs/puppetlabs-concat.git" + concat: + repo: "git://github.com/puppetlabs/puppetlabs-concat.git" + branch: "1.2.x" portage: "git://github.com/gentoo/puppet-portage.git" symlinks: apache: "#{source_dir}" diff --git a/apache/README.md b/apache/README.md index 5a6a356fa..c64da7ae8 100644 --- a/apache/README.md +++ b/apache/README.md @@ -347,6 +347,10 @@ Sets the amount of time the server waits for subsequent requests on a persistent Sets the limit of the number of requests allowed per connection when KeepAlive is on. Defaults to '100'. +#####`lib_path` + +Specifies the location where apache module files are stored. It should not be configured manually without special reason. + #####`loadfile_name` Sets the file name for the module loadfile. Should be in the format *.load. This can be used to set the module load order. @@ -811,9 +815,9 @@ Installs Apache mod_status and uses the status.conf.erb template. These are the ```puppet class { 'apache::mod::status': - allow_from = ['127.0.0.1','::1'], - extended_status = 'On', - status_path = '/server-status', + allow_from => ['127.0.0.1','::1'], + extended_status => 'On', + status_path => '/server-status', ){ @@ -826,9 +830,9 @@ Installs Apache mod_expires and uses the expires.conf.erb template. These are th ```puppet class { 'apache::mod::expires': - expires_active = true, - expires_default = undef, - expires_by_type = undef, + expires_active => true, + expires_default => undef, + expires_by_type => undef, ){ @@ -839,7 +843,7 @@ Installs Apache mod_expires and uses the expires.conf.erb template. These are th ```puppet class { 'apache::mod::expires': - expires_by_type = [ + expires_by_type => [ { 'text/json' => 'access plus 1 month' }, { 'text/html' => 'access plus 1 year' }, ] @@ -868,8 +872,8 @@ To specify an alternate mod\_wsgi package name to install and the name of the mo wsgi_socket_prefix => "\${APACHE_RUN_DIR}WSGI", wsgi_python_home => '/path/to/venv', wsgi_python_path => '/path/to/venv/site-packages', - package_name => 'python27-mod_wsgi', - mod_path => 'python27-mod_wsgi.so', + package_name => 'python27-mod_wsgi', + mod_path => 'python27-mod_wsgi.so', } ``` diff --git a/apache/lib/puppet/parser/functions/validate_apache_log_level.rb b/apache/lib/puppet/parser/functions/validate_apache_log_level.rb new file mode 100644 index 000000000..8a1ade0be --- /dev/null +++ b/apache/lib/puppet/parser/functions/validate_apache_log_level.rb @@ -0,0 +1,27 @@ +module Puppet::Parser::Functions + newfunction(:validate_apache_log_level, :doc => <<-'ENDHEREDOC') do |args| + Perform simple validation of a string against the list of known log + levels as per http://httpd.apache.org/docs/current/mod/core.html#loglevel + validate_apache_loglevel('info') + + Modules maybe specified with their own levels like these: + validate_apache_loglevel('warn ssl:info') + validate_apache_loglevel('warn mod_ssl.c:info') + validate_apache_loglevel('warn ssl_module:info') + + Expected to be used from the main or vhost. + + Might be used from directory too later as apaceh supports that + + ENDHEREDOC + if (args.size != 1) then + raise Puppet::ParseError, ("validate_apache_loglevel(): wrong number of arguments (#{args.length}; must be 1)") + end + + log_level = args[0] + msg = "Log level '${log_level}' is not one of the supported Apache HTTP Server log levels." + + raise Puppet::ParseError, (msg) unless log_level =~ Regexp.compile('(emerg|alert|crit|error|warn|notice|info|debug|trace[1-8])') + + end +end diff --git a/apache/manifests/dev.pp b/apache/manifests/dev.pp index 6bd865606..b1947e934 100644 --- a/apache/manifests/dev.pp +++ b/apache/manifests/dev.pp @@ -1,7 +1,4 @@ class apache::dev { - if $::osfamily == 'FreeBSD' and !defined(Class['apache::package']) { - fail('apache::dev requires apache::package; please include apache or apache::package class first') - } include ::apache::params $packages = $::apache::params::dev_packages if $packages { # FreeBSD doesn't have dev packages to install diff --git a/apache/manifests/init.pp b/apache/manifests/init.pp index 0b8544f93..37d866ad6 100644 --- a/apache/manifests/init.pp +++ b/apache/manifests/init.pp @@ -48,6 +48,7 @@ $mod_dir = $::apache::params::mod_dir, $mod_enable_dir = $::apache::params::mod_enable_dir, $mpm_module = $::apache::params::mpm_module, + $lib_path = $::apache::params::lib_path, $conf_template = $::apache::params::conf_template, $servername = $::apache::params::servername, $manage_user = true, @@ -124,10 +125,7 @@ } } - $valid_log_level_re = '(emerg|alert|crit|error|warn|notice|info|debug)' - - validate_re($log_level, $valid_log_level_re, - "Log level '${log_level}' is not one of the supported Apache HTTP Server log levels.") + validate_apache_log_level($log_level) class { '::apache::service': service_name => $service_name, diff --git a/apache/manifests/mod.pp b/apache/manifests/mod.pp index 0891bf0b7..bc52d2e20 100644 --- a/apache/manifests/mod.pp +++ b/apache/manifests/mod.pp @@ -2,7 +2,7 @@ $package = undef, $package_ensure = 'present', $lib = undef, - $lib_path = $::apache::params::lib_path, + $lib_path = $::apache::lib_path, $id = undef, $path = undef, $loadfile_name = undef, diff --git a/apache/manifests/mod/expires.pp b/apache/manifests/mod/expires.pp index 8c1ce8441..10542916a 100644 --- a/apache/manifests/mod/expires.pp +++ b/apache/manifests/mod/expires.pp @@ -6,9 +6,9 @@ ::apache::mod { 'expires': } # Template uses - # $expries_active - # $expries_default - # $expries_by_type + # $expires_active + # $expires_default + # $expires_by_type file { 'expires.conf': ensure => file, path => "${::apache::mod_dir}/expires.conf", diff --git a/apache/manifests/mod/wsgi.pp b/apache/manifests/mod/wsgi.pp index 80f9738ff..bff5b46b7 100644 --- a/apache/manifests/mod/wsgi.pp +++ b/apache/manifests/mod/wsgi.pp @@ -14,7 +14,7 @@ if $mod_path =~ /\// { $_mod_path = $mod_path } else { - $_mod_path = "${::apache::params::lib_path}/${mod_path}" + $_mod_path = "${::apache::lib_path}/${mod_path}" } ::apache::mod { 'wsgi': package => $package_name, diff --git a/apache/manifests/mpm.pp b/apache/manifests/mpm.pp index a5cca4988..2478184f5 100644 --- a/apache/manifests/mpm.pp +++ b/apache/manifests/mpm.pp @@ -1,5 +1,5 @@ define apache::mpm ( - $lib_path = $::apache::params::lib_path, + $lib_path = $::apache::lib_path, $apache_version = $::apache::apache_version, ) { if ! defined(Class['apache']) { diff --git a/apache/manifests/package.pp b/apache/manifests/package.pp index 395c03103..728b26010 100644 --- a/apache/manifests/package.pp +++ b/apache/manifests/package.pp @@ -2,6 +2,12 @@ $ensure = 'present', $mpm_module = $::apache::params::mpm_module, ) inherits ::apache::params { + + # The base class must be included first because it is used by parameter defaults + if ! defined(Class['apache']) { + fail('You must include the apache base class before using any apache defined resources') + } + case $::osfamily { 'FreeBSD': { case $mpm_module { @@ -44,10 +50,10 @@ before => Package['httpd'], } } - $apache_package = $::apache::params::apache_name + $apache_package = $::apache::apache_name } default: { - $apache_package = $::apache::params::apache_name + $apache_package = $::apache::apache_name } } diff --git a/apache/manifests/vhost.pp b/apache/manifests/vhost.pp index 70d2a57bb..bbb5e61f2 100644 --- a/apache/manifests/vhost.pp +++ b/apache/manifests/vhost.pp @@ -125,7 +125,7 @@ fail('You must include the apache base class before using any apache defined resources') } - $apache_name = $::apache::params::apache_name + $apache_name = $::apache::apache_name validate_re($ensure, '^(present|absent)$', "${ensure} is not supported for ensure. @@ -186,8 +186,7 @@ Allowed values are 'directory' and 'absent'.") if $log_level { - validate_re($log_level, '^(emerg|alert|crit|error|warn|notice|info|debug)$', - "Log level '${log_level}' is not one of the supported Apache HTTP Server log levels.") + validate_apache_log_level($log_level) } if $access_log_file and $access_log_pipe { @@ -625,9 +624,10 @@ # Template uses: # - $proxy_dest # - $proxy_pass + # - $proxy_pass_match # - $proxy_preserve_host # - $no_proxy_uris - if $proxy_dest or $proxy_pass { + if $proxy_dest or $proxy_pass or $proxy_pass_match { concat::fragment { "${name}-proxy": target => "${priority_real}${filename}.conf", order => 140, diff --git a/apache/spec/acceptance/vhost_spec.rb b/apache/spec/acceptance/vhost_spec.rb index 6fe87c5a8..b5d51e91f 100644 --- a/apache/spec/acceptance/vhost_spec.rb +++ b/apache/spec/acceptance/vhost_spec.rb @@ -119,6 +119,33 @@ class { 'apache': } end end + context 'new proxy vhost on port 80' do + it 'should configure an apache proxy vhost' do + pp = <<-EOS + class { 'apache': } + apache::vhost { 'proxy.example.com': + port => '80', + docroot => '/var/www/proxy', + proxy_pass_match => [ + { 'path' => '/foo', 'url' => 'http://backend-foo/'}, + ], + proxy_preserve_host => true, + proxy_error_override => true, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{$vhost_dir}/25-proxy.example.com.conf") do + it { is_expected.to contain '' } + it { is_expected.to contain "ServerName proxy.example.com" } + it { is_expected.to contain "ProxyPassMatch /foo http://backend-foo/" } + it { is_expected.to contain "ProxyPreserveHost On" } + it { is_expected.to contain "ProxyErrorOverride On" } + it { is_expected.not_to contain "" } + end + end + context 'new vhost on port 80' do it 'should configure two apache vhosts' do pp = <<-EOS @@ -498,6 +525,47 @@ class { 'apache': default_vhost => false, } end end + context 'proxy_pass_match for alternative vhost' do + it 'should configure a local vhost and a proxy vhost' do + apply_manifest(%{ + class { 'apache': default_vhost => false, } + apache::vhost { 'localhost': + docroot => '/var/www/local', + ip => '127.0.0.1', + port => '8888', + } + apache::listen { '*:80': } + apache::vhost { 'proxy.example.com': + docroot => '/var/www', + port => '80', + add_listen => false, + proxy_pass_match => { + 'path' => '/', + 'url' => 'http://localhost:8888/subdir/', + }, + } + host { 'proxy.example.com': ip => '127.0.0.1', } + file { ['/var/www/local', '/var/www/local/subdir']: ensure => directory, } + file { '/var/www/local/subdir/index.html': + ensure => file, + content => "Hello from localhost\\n", + } + }, :catch_failures => true) + end + + describe service($service_name) do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end + + it 'should get a response from the back end' do + shell("/usr/bin/curl --max-redirs 0 proxy.example.com:80") do |r| + expect(r.stdout).to eq("Hello from localhost\n") + expect(r.exit_code).to eq(0) + end + end + end + describe 'ip_based' do it 'applies cleanly' do pp = <<-EOS diff --git a/apache/spec/classes/dev_spec.rb b/apache/spec/classes/dev_spec.rb index e2e0b47af..eb3d76593 100644 --- a/apache/spec/classes/dev_spec.rb +++ b/apache/spec/classes/dev_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' describe 'apache::dev', :type => :class do + let(:pre_condition) {[ + 'include apache' + ]} context "on a Debian OS" do let :facts do { @@ -9,6 +12,10 @@ :operatingsystem => 'Debian', :operatingsystemrelease => '6', :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => 'Linux' } end it { is_expected.to contain_class("apache::params") } @@ -25,6 +32,10 @@ :operatingsystem => 'Ubuntu', :operatingsystemrelease => '14.04', :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => 'Linux' } end it { is_expected.to contain_package("apache2-dev") } @@ -36,29 +47,31 @@ :operatingsystem => 'RedHat', :operatingsystemrelease => '6', :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => 'Linux' } end it { is_expected.to contain_class("apache::params") } it { is_expected.to contain_package("httpd-devel") } end context "on a FreeBSD OS" do - let :pre_condition do - 'include apache::package' - end let :facts do { :osfamily => 'FreeBSD', :operatingsystem => 'FreeBSD', :operatingsystemrelease => '9', :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => 'FreeBSD' } end it { is_expected.to contain_class("apache::params") } end context "on a Gentoo OS" do - let :pre_condition do - 'include apache::package' - end let :facts do { :osfamily => 'Gentoo', @@ -66,6 +79,10 @@ :operatingsystemrelease => '3.16.1-gentoo', :concat_basedir => '/dne', :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => 'Linux' } end it { is_expected.to contain_class("apache::params") } diff --git a/apache/spec/classes/mod/dev_spec.rb b/apache/spec/classes/mod/dev_spec.rb index f65338977..1686a0275 100644 --- a/apache/spec/classes/mod/dev_spec.rb +++ b/apache/spec/classes/mod/dev_spec.rb @@ -1,16 +1,14 @@ require 'spec_helper' describe 'apache::mod::dev', :type => :class do + let(:pre_condition) {[ + 'include apache' + ]} [ - ['RedHat', '6', 'Santiago'], - ['Debian', '6', 'squeeze'], - ['FreeBSD', '9', 'FreeBSD'], - ].each do |osfamily, operatingsystemrelease, lsbdistcodename| - if osfamily == 'FreeBSD' - let :pre_condition do - 'include apache::package' - end - end + ['RedHat', '6', 'Santiago', 'Linux'], + ['Debian', '6', 'squeeze', 'Linux'], + ['FreeBSD', '9', 'FreeBSD', 'FreeBSD'], + ].each do |osfamily, operatingsystemrelease, lsbdistcodename, kernel| context "on a #{osfamily} OS" do let :facts do { @@ -19,6 +17,10 @@ :operatingsystem => osfamily, :operatingsystemrelease => operatingsystemrelease, :is_pe => false, + :concat_basedir => '/foo', + :id => 'root', + :path => '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin', + :kernel => kernel } end it { is_expected.to contain_class('apache::dev') } diff --git a/apache/spec/unit/puppet/parser/functions/validate_apache_log_level.rb b/apache/spec/unit/puppet/parser/functions/validate_apache_log_level.rb new file mode 100644 index 000000000..dfef66eea --- /dev/null +++ b/apache/spec/unit/puppet/parser/functions/validate_apache_log_level.rb @@ -0,0 +1,39 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the validate_apache_log_level function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("validate_apache_log_level")).to eq("function_validate_apache_log_level") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_validate_apache_log_level([]) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given garbage" do + expect { scope.function_validate_apache_log_level(['garbage']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should not raise a ParseError when given a plain log level" do + expect { scope.function_validate_apache_log_level(['info']) }.to_not raise_error + end + + it "should not raise a ParseError when given a log level and module log level" do + expect { scope.function_validate_apache_log_level(['warn ssl:info']) }.to_not raise_error + end + + it "should not raise a ParseError when given a log level and module log level" do + expect { scope.function_validate_apache_log_level(['warn mod_ssl.c:info']) }.to_not raise_error + end + + it "should not raise a ParseError when given a log level and module log level" do + expect { scope.function_validate_apache_log_level(['warn ssl_module:info']) }.to_not raise_error + end + + it "should not raise a ParseError when given a trace level" do + expect { scope.function_validate_apache_log_level(['trace4']) }.to_not raise_error + end + +end diff --git a/ceilometer/.fixtures.yml b/ceilometer/.fixtures.yml index 8e65f3bb6..5e57356ff 100644 --- a/ceilometer/.fixtures.yml +++ b/ceilometer/.fixtures.yml @@ -1,9 +1,10 @@ fixtures: repositories: 'apache': 'git://github.com/puppetlabs/puppetlabs-apache.git' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'ref': '1.2.1' 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' 'keystone': 'git://github.com/stackforge/puppet-keystone.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' 'nova': 'git://github.com/stackforge/puppet-nova.git' diff --git a/ceilometer/LICENSE b/ceilometer/LICENSE index dd5b3a58a..88a11a0e7 100644 --- a/ceilometer/LICENSE +++ b/ceilometer/LICENSE @@ -1,174 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2012 OpenStack Foundation - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +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 - 1. Definitions. + http://www.apache.org/licenses/LICENSE-2.0 - "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. +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/ceilometer/manifests/collector.pp b/ceilometer/manifests/collector.pp index 3088fb419..c651a01bb 100644 --- a/ceilometer/manifests/collector.pp +++ b/ceilometer/manifests/collector.pp @@ -13,16 +13,38 @@ # (optional) ensure state for package. # Defaults to 'present' # +# [*udp_address*] +# (optional) the ceilometer collector udp bind address. +# Set it empty to disable the collector listener. +# Defaults to '0.0.0.0' +# +# [*udp_port*] +# (optional) the ceilometer collector udp bind port. +# Defaults to '4952' +# class ceilometer::collector ( $manage_service = true, $enabled = true, $package_ensure = 'present', + $udp_address = '0.0.0.0', + $udp_port = '4952', ) { include ::ceilometer::params Ceilometer_config<||> ~> Service['ceilometer-collector'] + # We accept udp_address to be set to empty instead of the usual undef to stay + # close to the "strange" upstream interface. + if (is_ip_address($udp_address) != true and $udp_address != '' ){ + fail("${udp_address} is not a valid ip and is not empty") + } + + ceilometer_config { + 'collector/udp_address' : value => $udp_address; + 'collector/udp_port' : value => $udp_port; + } + Package[$::ceilometer::params::collector_package_name] -> Service['ceilometer-collector'] ensure_resource( 'package', [$::ceilometer::params::collector_package_name], { ensure => $package_ensure } diff --git a/ceilometer/spec/classes/ceilometer_agent_polling_spec.rb b/ceilometer/spec/classes/ceilometer_agent_polling_spec.rb index 289214689..c729031d2 100644 --- a/ceilometer/spec/classes/ceilometer_agent_polling_spec.rb +++ b/ceilometer/spec/classes/ceilometer_agent_polling_spec.rb @@ -21,30 +21,30 @@ shared_examples_for 'ceilometer-polling' do - it { should contain_class('ceilometer::params') } + it { is_expected.to contain_class('ceilometer::params') } context 'when compute_namespace => true' do it 'adds ceilometer user to nova group and, if required, to libvirt group' do if platform_params[:libvirt_group] - should contain_user('ceilometer').with_groups(['nova', "#{platform_params[:libvirt_group]}"]) + is_expected.to contain_user('ceilometer').with_groups(['nova', "#{platform_params[:libvirt_group]}"]) else - should contain_user('ceilometer').with_groups('nova') + is_expected.to contain_user('ceilometer').with_groups('nova') end end it 'ensures nova-common is installed before the package ceilometer-common' do - should contain_package('nova-common').with( + is_expected.to contain_package('nova-common').with( :before => /Package\[ceilometer-common\]/ ) end it 'configures nova notification driver' do - should contain_file_line_after('nova-notification-driver-common').with( + is_expected.to contain_file_line_after('nova-notification-driver-common').with( :line => 'notification_driver=nova.openstack.common.notifier.rpc_notifier', :path => '/etc/nova/nova.conf', :notify => 'Service[nova-compute]' ) - should contain_file_line_after('nova-notification-driver-ceilometer').with( + is_expected.to contain_file_line_after('nova-notification-driver-ceilometer').with( :line => 'notification_driver=ceilometer.compute.nova_notifier', :path => '/etc/nova/nova.conf', :notify => 'Service[nova-compute]' @@ -53,7 +53,7 @@ end it 'installs ceilometer-polling package' do - should contain_package('ceilometer-polling').with( + is_expected.to contain_package('ceilometer-polling').with( :ensure => 'latest', :name => platform_params[:agent_package_name], :before => /Service\[ceilometer-polling\]/, @@ -62,11 +62,11 @@ end it 'configures central agent' do - should contain_ceilometer_config('DEFAULT/polling_namespaces').with_value('central,compute,ipmi') + is_expected.to contain_ceilometer_config('DEFAULT/polling_namespaces').with_value('central,compute,ipmi') end it 'ensures ceilometer-common is installed before the service' do - should contain_package('ceilometer-common').with( + is_expected.to contain_package('ceilometer-common').with( :before => /Service\[ceilometer-polling\]/ ) end @@ -78,7 +78,7 @@ end it 'configures ceilometer-polling service' do - should contain_service('ceilometer-polling').with( + is_expected.to contain_service('ceilometer-polling').with( :ensure => (params[:manage_service] && params[:enabled]) ? 'running' : 'stopped', :name => platform_params[:agent_service_name], :enable => params[:enabled], @@ -97,7 +97,7 @@ end it 'configures ceilometer-polling service' do - should contain_service('ceilometer-polling').with( + is_expected.to contain_service('ceilometer-polling').with( :ensure => nil, :name => platform_params[:agent_service_name], :enable => false, @@ -108,7 +108,7 @@ end it 'configures central agent' do - should contain_ceilometer_config('coordination/backend_url').with_value( params[:coordination_url] ) + is_expected.to contain_ceilometer_config('coordination/backend_url').with_value( params[:coordination_url] ) end end diff --git a/ceilometer/spec/classes/ceilometer_api_spec.rb b/ceilometer/spec/classes/ceilometer_api_spec.rb index 7b0c87500..e54eea1a9 100644 --- a/ceilometer/spec/classes/ceilometer_api_spec.rb +++ b/ceilometer/spec/classes/ceilometer_api_spec.rb @@ -165,12 +165,12 @@ }) end it 'configures identity_uri' do - should contain_ceilometer_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:1234/"); + is_expected.to contain_ceilometer_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:1234/"); # since only auth_uri is set the deprecated auth parameters should # still get set in case they are still in use - should contain_ceilometer_config('keystone_authtoken/auth_host').with_value('127.0.0.1'); - should contain_ceilometer_config('keystone_authtoken/auth_port').with_value('35357'); - should contain_ceilometer_config('keystone_authtoken/auth_protocol').with_value('http'); + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_host').with_value('127.0.0.1'); + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_port').with_value('35357'); + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_protocol').with_value('http'); end end @@ -185,12 +185,12 @@ }) end it 'configures identity_uri and auth_uri but deprecates old auth settings' do - should contain_ceilometer_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:35357/"); - should contain_ceilometer_config('keystone_authtoken/auth_uri').with_value("https://foo.bar:5000/v2.0/"); - should contain_ceilometer_config('keystone_authtoken/auth_admin_prefix').with(:ensure => 'absent') - should contain_ceilometer_config('keystone_authtoken/auth_port').with(:ensure => 'absent') - should contain_ceilometer_config('keystone_authtoken/auth_protocol').with(:ensure => 'absent') - should contain_ceilometer_config('keystone_authtoken/auth_host').with(:ensure => 'absent') + is_expected.to contain_ceilometer_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:35357/"); + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_uri').with_value("https://foo.bar:5000/v2.0/"); + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_admin_prefix').with(:ensure => 'absent') + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_port').with(:ensure => 'absent') + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_protocol').with(:ensure => 'absent') + is_expected.to contain_ceilometer_config('keystone_authtoken/auth_host').with(:ensure => 'absent') end end diff --git a/ceilometer/spec/classes/ceilometer_collector_spec.rb b/ceilometer/spec/classes/ceilometer_collector_spec.rb index 314c61b94..7b3261eef 100644 --- a/ceilometer/spec/classes/ceilometer_collector_spec.rb +++ b/ceilometer/spec/classes/ceilometer_collector_spec.rb @@ -8,6 +8,39 @@ shared_examples_for 'ceilometer-collector' do + context 'when invalid ip is passed' do + let :params do + { :udp_address => '300.0.0.0' } + end + it 'should fail' do + is_expected.to raise_error(Puppet::Error, /is not a valid ip and is not empty/) + end + end + + context 'when a valid ipv6 is passed' do + before do + pre_condition << "class { 'ceilometer::db': }" + end + let :params do + { :udp_address => '::1' } + end + it 'shouldn\'t fail' do + is_expected.to_not raise_error + end + end + + context 'when an empty string passed' do + before do + pre_condition << "class { 'ceilometer::db': }" + end + let :params do + { :udp_address => '' } + end + it 'should disable the listener' do + is_expected.to contain_ceilometer_config('collector/udp_address').with_value( '' ) + end + end + context 'when enabled' do before do pre_condition << "class { 'ceilometer::db': }" @@ -15,6 +48,11 @@ it { is_expected.to contain_class('ceilometer::params') } + it 'configures ceilometer-collector server' do + is_expected.to contain_ceilometer_config('collector/udp_address').with_value( '0.0.0.0' ) + is_expected.to contain_ceilometer_config('collector/udp_port').with_value( '4952' ) + end + it 'installs ceilometer-collector package' do is_expected.to contain_package(platform_params[:collector_package_name]).with( :ensure => 'present' @@ -44,7 +82,6 @@ # Catalog compilation does not crash for lack of ceilometer::db it { is_expected.to compile } - it 'configures ceilometer-collector service' do is_expected.to contain_service('ceilometer-collector').with( :ensure => 'stopped', diff --git a/ceilometer/spec/unit/provider/ceilometer_config/ini_setting_spec.rb b/ceilometer/spec/unit/provider/ceilometer_config/ini_setting_spec.rb new file mode 100644 index 000000000..172766dc2 --- /dev/null +++ b/ceilometer/spec/unit/provider/ceilometer_config/ini_setting_spec.rb @@ -0,0 +1,42 @@ +$LOAD_PATH.push( + File.join( + File.dirname(__FILE__), + '..', + '..', + '..', + 'fixtures', + 'modules', + 'inifile', + 'lib') +) + +require 'spec_helper' + +provider_class = Puppet::Type.type(:ceilometer_config).provider(:ini_setting) + +describe provider_class do + + it 'should default to the default setting when no other one is specified' do + resource = Puppet::Type::Ceilometer_config.new( + { + :name => 'DEFAULT/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('DEFAULT') + expect(provider.setting).to eq('foo') + end + + it 'should allow setting to be set explicitly' do + resource = Puppet::Type::Ceilometer_config.new( + { + :name => 'dude/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('dude') + expect(provider.setting).to eq('foo') + end +end diff --git a/ceilometer/spec/unit/type/ceilometer_config_spec.rb b/ceilometer/spec/unit/type/ceilometer_config_spec.rb new file mode 100644 index 000000000..226507eb9 --- /dev/null +++ b/ceilometer/spec/unit/type/ceilometer_config_spec.rb @@ -0,0 +1,53 @@ +require 'puppet' +require 'puppet/type/ceilometer_config' + +describe 'Puppet::Type.type(:ceilometer_config)' do + before :each do + @ceilometer_config = Puppet::Type.type(:ceilometer_config).new(:name => 'DEFAULT/foo', :value => 'bar') + end + + it 'should require a name' do + expect { + Puppet::Type.type(:ceilometer_config).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + + it 'should not expect a name with whitespace' do + expect { + Puppet::Type.type(:ceilometer_config).new(:name => 'f oo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should fail when there is no section' do + expect { + Puppet::Type.type(:ceilometer_config).new(:name => 'foo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should not require a value when ensure is absent' do + Puppet::Type.type(:ceilometer_config).new(:name => 'DEFAULT/foo', :ensure => :absent) + end + + it 'should accept a valid value' do + @ceilometer_config[:value] = 'bar' + expect(@ceilometer_config[:value]).to eq('bar') + end + + it 'should not accept a value with whitespace' do + @ceilometer_config[:value] = 'b ar' + expect(@ceilometer_config[:value]).to eq('b ar') + end + + it 'should accept valid ensure values' do + @ceilometer_config[:ensure] = :present + expect(@ceilometer_config[:ensure]).to eq(:present) + @ceilometer_config[:ensure] = :absent + expect(@ceilometer_config[:ensure]).to eq(:absent) + end + + it 'should not accept invalid ensure values' do + expect { + @ceilometer_config[:ensure] = :latest + }.to raise_error(Puppet::Error, /Invalid value/) + end +end diff --git a/glance/LICENSE b/glance/LICENSE index 8d968b6cb..8961ce8a6 100644 --- a/glance/LICENSE +++ b/glance/LICENSE @@ -1,201 +1,15 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright (C) 2012 Puppet Labs Inc - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Puppet Labs can be contacted at: info@puppetlabs.com - 1. Definitions. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. + http://www.apache.org/licenses/LICENSE-2.0 - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "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. +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/glance/lib/puppet/provider/glance.rb b/glance/lib/puppet/provider/glance.rb index 6f7bbee06..2501d63c9 100644 --- a/glance/lib/puppet/provider/glance.rb +++ b/glance/lib/puppet/provider/glance.rb @@ -16,7 +16,7 @@ def self.get_glance_credentials glance_file['keystone_authtoken']['admin_tenant_name'] and glance_file['keystone_authtoken']['admin_user'] and glance_file['keystone_authtoken']['admin_password'] and - glance_file['DEFAULT']['os_region_name'] + glance_file['glance_store']['os_region_name'] g = {} g['auth_host'] = glance_file['keystone_authtoken']['auth_host'].strip @@ -25,7 +25,7 @@ def self.get_glance_credentials g['admin_tenant_name'] = glance_file['keystone_authtoken']['admin_tenant_name'].strip g['admin_user'] = glance_file['keystone_authtoken']['admin_user'].strip g['admin_password'] = glance_file['keystone_authtoken']['admin_password'].strip - g['os_region_name'] = glance_file['DEFAULT']['os_region_name'].strip + g['os_region_name'] = glance_file['glance_store']['os_region_name'].strip # auth_admin_prefix not required to be set. g['auth_admin_prefix'] = (glance_file['keystone_authtoken']['auth_admin_prefix'] || '').strip @@ -36,14 +36,14 @@ def self.get_glance_credentials glance_file['keystone_authtoken']['admin_tenant_name'] and glance_file['keystone_authtoken']['admin_user'] and glance_file['keystone_authtoken']['admin_password'] and - glance_file['DEFAULT']['os_region_name'] + glance_file['glance_store']['os_region_name'] g = {} g['identity_uri'] = glance_file['keystone_authtoken']['identity_uri'].strip g['admin_tenant_name'] = glance_file['keystone_authtoken']['admin_tenant_name'].strip g['admin_user'] = glance_file['keystone_authtoken']['admin_user'].strip g['admin_password'] = glance_file['keystone_authtoken']['admin_password'].strip - g['os_region_name'] = glance_file['DEFAULT']['os_region_name'].strip + g['os_region_name'] = glance_file['glance_store']['os_region_name'].strip return g else diff --git a/glance/lib/puppet/provider/glance_image/glance.rb b/glance/lib/puppet/provider/glance_image/glance.rb index 7be1ace9d..fae22e032 100644 --- a/glance/lib/puppet/provider/glance_image/glance.rb +++ b/glance/lib/puppet/provider/glance_image/glance.rb @@ -92,10 +92,6 @@ def destroy @property_hash[:ensure] = :absent end - def location=(value) - auth_glance('image-update', id, "--location=#{value}") - end - def is_public=(value) auth_glance('image-update', id, "--is-public=#{value}") end diff --git a/glance/lib/puppet/type/glance_image.rb b/glance/lib/puppet/type/glance_image.rb index 8ee348a9a..10e577efe 100644 --- a/glance/lib/puppet/type/glance_image.rb +++ b/glance/lib/puppet/type/glance_image.rb @@ -36,7 +36,7 @@ end end - newproperty(:location) do + newparam(:location) do desc "The permanent location of the image. Optional" newvalues(/\S+/) end diff --git a/glance/manifests/api.pp b/glance/manifests/api.pp index bb58e9100..26dc0b386 100644 --- a/glance/manifests/api.pp +++ b/glance/manifests/api.pp @@ -8,7 +8,9 @@ # (required) Password used to authentication. # # [*package_ensure*] -# (optional) Ensure state for package. Defaults to 'present'. +# (optional) Ensure state for package. On RedHat platforms this +# setting is ignored and the setting from the glance class is used +# because there is only one glance package. Defaults to 'present'. # # [*verbose*] # (optional) Rather to log the glance api service at verbose level. @@ -237,12 +239,14 @@ warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') } - ensure_packages([$glance::params::api_package_name], - { - ensure => $package_ensure, - tag => ['openstack'], - } - ) + if ( $glance::params::api_package_name != $glance::params::registry_package_name ) { + ensure_packages([$glance::params::api_package_name], + { + ensure => $package_ensure, + tag => ['openstack'], + } + ) + } Package[$glance::params::api_package_name] -> File['/etc/glance/'] Package[$glance::params::api_package_name] -> Class['glance::policy'] diff --git a/glance/manifests/init.pp b/glance/manifests/init.pp index 5dec9033b..3b1042252 100644 --- a/glance/manifests/init.pp +++ b/glance/manifests/init.pp @@ -2,7 +2,16 @@ # == class: glance # # base glance config. # -class glance { +# === parameters: +# +# [*package_ensure*] +# (Optional) Ensure state for package. On Ubuntu this setting +# is ignored since Ubuntu has separate API and registry packages. +# Defaults to 'present' +# +class glance( + $package_ensure = 'present' +) { include ::glance::params @@ -12,4 +21,12 @@ # == class: glance group => 'root', mode => '0770', } + + if ( $glance::params::api_package_name == $glance::params::registry_package_name ) { + package { $glance::params::api_package_name : + ensure => $package_ensure, + name => $::glance::params::package_name, + tag => ['openstack'], + } + } } diff --git a/glance/manifests/params.pp b/glance/manifests/params.pp index 8be763a13..61df5b8db 100644 --- a/glance/manifests/params.pp +++ b/glance/manifests/params.pp @@ -10,8 +10,8 @@ case $::osfamily { 'RedHat': { - $api_package_name = 'openstack-glance-api' - $registry_package_name = 'openstack-glance-registry' + $api_package_name = 'openstack-glance' + $registry_package_name = 'openstack-glance' $api_service_name = 'openstack-glance-api' $registry_service_name = 'openstack-glance-registry' $db_sync_command = 'glance-manage --config-file=/etc/glance/glance-registry.conf db_sync' diff --git a/glance/manifests/registry.pp b/glance/manifests/registry.pp index e11a9b086..b30d7f565 100644 --- a/glance/manifests/registry.pp +++ b/glance/manifests/registry.pp @@ -8,7 +8,9 @@ # (required) The keystone password for administrative user # # [*package_ensure*] -# (optional) Ensure state for package. Defaults to 'present'. +# (optional) Ensure state for package. Defaults to 'present'. On RedHat +# platforms this setting is ignored and the setting from the glance class is +# used because there is only one glance package. # # [*verbose*] # (optional) Enable verbose logs (true|false). Defaults to false. @@ -160,12 +162,14 @@ warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') } - ensure_packages( [$glance::params::registry_package_name], - { - ensure => $package_ensure, - tag => ['openstack'], - } - ) + if ( $glance::params::api_package_name != $glance::params::registry_package_name ) { + ensure_packages( [$glance::params::registry_package_name], + { + ensure => $package_ensure, + tag => ['openstack'], + } + ) + } Package[$glance::params::registry_package_name] -> File['/etc/glance/'] Package[$glance::params::registry_package_name] -> Glance_registry_config<||> diff --git a/glance/spec/classes/glance_api_spec.rb b/glance/spec/classes/glance_api_spec.rb index f796b4909..bdac287a0 100644 --- a/glance/spec/classes/glance_api_spec.rb +++ b/glance/spec/classes/glance_api_spec.rb @@ -434,6 +434,8 @@ end let(:params) { default_params } + # We only test this on Debian platforms, since on RedHat there isn't a + # separate package for glance API. ['present', 'latest'].each do |package_ensure| context "with package_ensure '#{package_ensure}'" do let(:params) { default_params.merge({ :package_ensure => package_ensure }) } @@ -451,15 +453,9 @@ end let(:params) { default_params } - ['present', 'latest'].each do |package_ensure| - context "with package_ensure '#{package_ensure}'" do - let(:params) { default_params.merge({ :package_ensure => package_ensure }) } - it { is_expected.to contain_package('openstack-glance-api').with( - :ensure => package_ensure, - :tag => ['openstack'] - )} - end - end + it { is_expected.to contain_package('openstack-glance').with( + :tag => ['openstack'], + )} end describe 'on unknown platforms' do diff --git a/glance/spec/classes/glance_cache_cleaner_spec.rb b/glance/spec/classes/glance_cache_cleaner_spec.rb index 6f9c34f81..ccb87845b 100644 --- a/glance/spec/classes/glance_cache_cleaner_spec.rb +++ b/glance/spec/classes/glance_cache_cleaner_spec.rb @@ -59,7 +59,7 @@ { :osfamily => 'RedHat' } end include_examples 'glance cache cleaner' - it { is_expected.to contain_cron('glance-cache-cleaner').with(:require => 'Package[openstack-glance-api]')} + it { is_expected.to contain_cron('glance-cache-cleaner').with(:require => 'Package[openstack-glance]')} end end diff --git a/glance/spec/classes/glance_cache_pruner_spec.rb b/glance/spec/classes/glance_cache_pruner_spec.rb index cc58932e7..1d08b33fc 100644 --- a/glance/spec/classes/glance_cache_pruner_spec.rb +++ b/glance/spec/classes/glance_cache_pruner_spec.rb @@ -59,7 +59,7 @@ { :osfamily => 'RedHat' } end include_examples 'glance cache pruner' - it { is_expected.to contain_cron('glance-cache-pruner').with(:require => 'Package[openstack-glance-api]')} + it { is_expected.to contain_cron('glance-cache-pruner').with(:require => 'Package[openstack-glance]')} end end diff --git a/glance/spec/classes/glance_registry_spec.rb b/glance/spec/classes/glance_registry_spec.rb index 34e3ae26c..2bb888ca2 100644 --- a/glance/spec/classes/glance_registry_spec.rb +++ b/glance/spec/classes/glance_registry_spec.rb @@ -347,6 +347,8 @@ { :osfamily => 'Debian' } end + # We only test this on Debian platforms, since on RedHat there isn't a + # separate package for glance registry. ['present', 'latest'].each do |package_ensure| context "with package_ensure '#{package_ensure}'" do let(:params) { default_params.merge({ :package_ensure => package_ensure }) } @@ -364,16 +366,7 @@ end let(:params) { default_params } - ['present', 'latest'].each do |package_ensure| - context "with package_ensure '#{package_ensure}'" do - let(:params) { default_params.merge({ :package_ensure => package_ensure }) } - it { is_expected.to contain_package('openstack-glance-registry').with( - :ensure => package_ensure, - :tag => ['openstack'] - )} - end - end - + it { is_expected.to contain_package('openstack-glance')} end describe 'on unknown platforms' do diff --git a/glance/spec/classes/glance_spec.rb b/glance/spec/classes/glance_spec.rb index 968b69764..075cec5eb 100644 --- a/glance/spec/classes/glance_spec.rb +++ b/glance/spec/classes/glance_spec.rb @@ -49,7 +49,9 @@ end let(:params) { default_params } - it { is_expected.to_not contain_package('openstack-glance') } + it { is_expected.to contain_package('openstack-glance').with( + :tag => ['openstack'], + )} end end diff --git a/glance/spec/unit/provider/glance_spec.rb b/glance/spec/unit/provider/glance_spec.rb index 14d418b97..344ec4a21 100644 --- a/glance/spec/unit/provider/glance_spec.rb +++ b/glance/spec/unit/provider/glance_spec.rb @@ -36,7 +36,7 @@ 'admin_user' => 'user', 'admin_password' => 'pass' }, - 'DEFAULT' => + 'glance_store' => { 'os_region_name' => 'SomeRegion', } diff --git a/gluster/manifests/brick.pp b/gluster/manifests/brick.pp index ee308f29c..69939f9b4 100644 --- a/gluster/manifests/brick.pp +++ b/gluster/manifests/brick.pp @@ -539,7 +539,7 @@ recurse => false, # don't recurse into directory purge => false, # don't purge unmanaged files force => false, # don't purge subdirs and links - require => Exec["gluster-brick-mkfs-${name}"], + require => Exec["gluster-brick-mkdir-${name}"], } } } diff --git a/gluster/manifests/mount.pp b/gluster/manifests/mount.pp index db437a35e..ae066f898 100644 --- a/gluster/manifests/mount.pp +++ b/gluster/manifests/mount.pp @@ -27,6 +27,8 @@ $ip = '', # you can specify which ip address to use (if multiple) $type = 'glusterfs', # use 'glusterfs' or 'nfs' $shorewall = false, + $owner = '', # mount owner + $group = '', # mount group ) { include gluster::params @@ -142,6 +144,14 @@ purge => false, # don't purge unmanaged files force => false, # don't purge subdirs and links alias => "${short_name}", # don't allow duplicates name's + owner => "${owner}" ? { # make sure owner is undef if not specified + '' => undef, + default => $owner, + }, + group => "${group}" ? { # make sure group is undef if not specified + '' => undef, + default => $group, + } } # TODO: review packages content against nfs fstype mount option diff --git a/gluster/manifests/volume/property/data.pp b/gluster/manifests/volume/property/data.pp index eaf7df2c8..356db3f8c 100644 --- a/gluster/manifests/volume/property/data.pp +++ b/gluster/manifests/volume/property/data.pp @@ -104,7 +104,7 @@ # Sets the quorum percentage for the trusted storage pool. 'cluster.server-quorum-ratio' => 'integer', # in % default: (null) - # If set to server, enables the specified volume to participate in quorum. + # If set to server, enables the specified volume to participate in quorum. 'cluster.server-quorum-type' => 'string', # default: (null) # Size of the stripe unit that would be read from or written to the striped servers. @@ -295,6 +295,9 @@ # Number of pages that will be pre-fetched 'performance.read-ahead-page-count' => 'integer', # default: 4 + # enable/disable readdir-ahead translator in the volume. + 'performance.readdir-ahead' => 'offon', # default: off + # enable/disable meta-data caching translator in the volume. 'performance.stat-prefetch' => 'onoff', # default: on diff --git a/gnocchi/spec/unit/provider/gnocchi_config/ini_setting_spec.rb b/gnocchi/spec/unit/provider/gnocchi_config/ini_setting_spec.rb index fa617c6bc..059a5a2f5 100644 --- a/gnocchi/spec/unit/provider/gnocchi_config/ini_setting_spec.rb +++ b/gnocchi/spec/unit/provider/gnocchi_config/ini_setting_spec.rb @@ -22,8 +22,8 @@ {:name => 'DEFAULT/foo', :value => 'bar'} ) provider = provider_class.new(resource) - provider.section.should == 'DEFAULT' - provider.setting.should == 'foo' + expect(provider.section).to eq('DEFAULT') + expect(provider.setting).to eq('foo') end it 'should allow setting to be set explicitly' do @@ -31,7 +31,7 @@ {:name => 'dude/foo', :value => 'bar'} ) provider = provider_class.new(resource) - provider.section.should == 'dude' - provider.setting.should == 'foo' + expect(provider.section).to eq('dude') + expect(provider.setting).to eq('foo') end end diff --git a/gnocchi/spec/unit/type/gnocchi_config_spec.rb b/gnocchi/spec/unit/type/gnocchi_config_spec.rb index 24a0caf75..d711b0345 100644 --- a/gnocchi/spec/unit/type/gnocchi_config_spec.rb +++ b/gnocchi/spec/unit/type/gnocchi_config_spec.rb @@ -29,19 +29,19 @@ it 'should accept a valid value' do @gnocchi_config[:value] = 'bar' - @gnocchi_config[:value].should == 'bar' + expect(@gnocchi_config[:value]).to eq('bar') end it 'should not accept a value with whitespace' do @gnocchi_config[:value] = 'b ar' - @gnocchi_config[:value].should == 'b ar' + expect(@gnocchi_config[:value]).to eq('b ar') end it 'should accept valid ensure values' do @gnocchi_config[:ensure] = :present - @gnocchi_config[:ensure].should == :present + expect(@gnocchi_config[:ensure]).to eq(:present) @gnocchi_config[:ensure] = :absent - @gnocchi_config[:ensure].should == :absent + expect(@gnocchi_config[:ensure]).to eq(:absent) end it 'should not accept invalid ensure values' do diff --git a/haproxy/.gitignore b/haproxy/.gitignore index b5db85e05..2652ac5e9 100644 --- a/haproxy/.gitignore +++ b/haproxy/.gitignore @@ -1,4 +1,5 @@ pkg/ +log/ Gemfile.lock vendor/ spec/fixtures/ diff --git a/haproxy/README.md b/haproxy/README.md index 0e4db97cf..9cd355750 100644 --- a/haproxy/README.md +++ b/haproxy/README.md @@ -280,7 +280,7 @@ Using storeconfigs, you can export the `haproxy::balancermember` resources on al Sets the backend service's name. Generally, it will be the namevar of the defined resource type. This value appears right after the 'backend' statement in haproxy.cfg #####`options` -A hash of options that are inserted into the backend service configuration block. +A hash or array of options that are inserted into the backend service configuration block. If you need to control exactly the order in which these options will appear in the backend service configuration block supply the options as an array of hashes, where each hash has one key-value pair that represents the option and its value. #####`collect_exported` Enables exported resources from `haproxy::balancermember` to be collected, serving as a form of autodiscovery. Displays as a Boolean and defaults to 'true'. @@ -303,6 +303,22 @@ haproxy::backend { 'puppet00': } ``` +If option order is important use an array of hashes for the `options` parameter to have the backend options appear in the resulting backend configuration block in the exact order in which they are specified in Puppet: + +```puppet +haproxy::backend { 'puppet00': + options => [ + { 'option' => [ + 'tcplog', + 'ssl-hello-chk', + ] + }, + { 'balance' => 'roundrobin' }, + { 'cookie' => 'C00 insert' }, + ], +} +``` + ####Defined type: `haproxy::frontend` This type sets up a frontend service configuration block in haproxy.cfg. The HAProxy daemon uses the directives in the .cfg file to determine which ports/IPs to listen on and route traffic on those ports/IPs to specified balancermembers. @@ -337,7 +353,7 @@ Sets the mode of operation for the frontend service. Valid values are 'undef', ' Sets the frontend service's name. Generally, it will be the namevar of the defined resource type. This value appears right after the 'fronted' statement in haproxy.cfg. #####`options` -A hash of options that are inserted into the frontend service configuration block. +A hash or array of options that are inserted into the backend service configuration block. If you need to control exactly the order in which these options will appear in the backend service configuration block supply the options as an array of hashes, where each hash has one key-value pair that represents the option and its value. See Example section right below. #####`ports` Sets the ports to listen on for the address specified in `ipaddress`. Accepts a single, comma-separated string or an array of strings, which may be ports or hyphenated port ranges. @@ -353,9 +369,8 @@ haproxy::frontend { 'puppet00': mode => 'tcp', bind_options => 'accept-proxy', options => { - 'option' => [ 'default_backend', 'puppet_backend00'], + 'default_backend' => 'puppet_backend00', 'timeout client' => '30', - 'balance' => 'roundrobin' 'option' => [ 'tcplog', 'accept-invalid-http-request', @@ -364,6 +379,26 @@ haproxy::frontend { 'puppet00': } ``` +If option order is important use an array of hashes for the `options` parameter to have the frontend options appear in the resulting frontned configuration block in the exact order in which they are specified in Puppet: + +```puppet +haproxy::frontend { 'puppet00': + ipaddress => $::ipaddress, + ports => '18140', + mode => 'tcp', + bind_options => 'accept-proxy', + options => [ + { 'default_backend' => 'puppet_backend00' }, + { 'timeout client' => '30' }, + { 'option' => [ + 'tcplog', + 'accept-invalid-http-request', + ], + } + ], +} +``` + ####Defined type: `haproxy::listen` This type sets up a listening service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each listening service configuration needs one or more load balancer member server (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type). @@ -405,7 +440,7 @@ Specifies the mode of operation for the listening service. Valid values are 'und Sets the listening service's name. Generally, it will be the namevar of the defined resource type. This value appears right after the 'listen' statement in haproxy.cfg. #####`options` -A hash of options that are inserted into the listening service configuration block. +A hash or array of options that are inserted into the backend service configuration block. If you need to control exactly the order in which these options will appear in the backend service configuration block supply the options as an array of hashes, where each hash has one key-value pair that represents the option and its value. See Example sections for backend and frontend above. #####`ports` Sets the ports to listen on for the address specified in `ipaddress`. Accepts a single, comma-separated string or an array of strings, which may be ports or hyphenated port ranges. @@ -485,7 +520,7 @@ Sets the port on which the peer is going to share the state. ##Limitations -RedHat and Debian family OSes are officially supported. Tested and built on Ubuntu and CentOS. +RedHat and Debian family OSes are officially supported. Tested and built on Ubuntu and CentOS. Also compatible with Gentoo. ##Development diff --git a/haproxy/manifests/install.pp b/haproxy/manifests/install.pp index 6856d1909..e5890a28a 100644 --- a/haproxy/manifests/install.pp +++ b/haproxy/manifests/install.pp @@ -8,4 +8,14 @@ ensure => $haproxy::_package_ensure, alias => 'haproxy', } + + # Create default configuration directory, gentoo portage does not create it + if $::osfamily == 'Gentoo' { + file { '/etc/haproxy': + ensure => directory, + owner => 'root', + group => 'root', + require => Package[$haproxy::package_name] + } + } } diff --git a/haproxy/manifests/params.pp b/haproxy/manifests/params.pp index 7ac6458d9..dc955244b 100644 --- a/haproxy/manifests/params.pp +++ b/haproxy/manifests/params.pp @@ -6,7 +6,7 @@ # class haproxy::params { case $::osfamily { - 'Archlinux', 'Debian', 'RedHat': { + 'Archlinux', 'Debian', 'Redhat', 'Gentoo' : { $package_name = 'haproxy' $global_options = { 'log' => "${::ipaddress} local0", diff --git a/haproxy/spec/classes/haproxy_spec.rb b/haproxy/spec/classes/haproxy_spec.rb index 0b1244e26..ab0d79dab 100644 --- a/haproxy/spec/classes/haproxy_spec.rb +++ b/haproxy/spec/classes/haproxy_spec.rb @@ -9,7 +9,7 @@ end context 'on supported platforms' do describe 'for OS-agnostic configuration' do - ['Debian', 'RedHat', 'Archlinux', 'FreeBSD',].each do |osfamily| + ['Debian', 'RedHat', 'Archlinux', 'FreeBSD', 'Gentoo',].each do |osfamily| context "on #{osfamily} family operatingsystems" do let(:facts) do { :osfamily => osfamily }.merge default_facts @@ -53,7 +53,7 @@ end describe 'for linux operating systems' do - ['Debian', 'RedHat', 'Archlinux', ].each do |osfamily| + ['Debian', 'RedHat', 'Archlinux', 'Gentoo', ].each do |osfamily| context "on #{osfamily} family operatingsystems" do let(:facts) do { :osfamily => osfamily }.merge default_facts @@ -337,6 +337,12 @@ { :osfamily => 'RedHat' }.merge default_facts end end + context 'only on Gentoo family operatingsystems' do + let(:facts) do + { :osfamily => 'Gentoo' }.merge default_facts + end + end + end end diff --git a/haproxy/spec/defines/frontend_spec.rb b/haproxy/spec/defines/frontend_spec.rb index aff45e3ef..977d8f432 100644 --- a/haproxy/spec/defines/frontend_spec.rb +++ b/haproxy/spec/defines/frontend_spec.rb @@ -213,5 +213,32 @@ ) } end + context "when frontend options are specified as an array of hashes" do + let(:params) do + { + :name => 'apache', + :bind => { + '0.0.0.0:48001-48003' => [], + }, + :mode => 'http', + :options => [ + { 'reqadd' => 'X-Forwarded-Proto:\ https' }, + { 'default_backend' => 'dev00_webapp' }, + { 'capture request header' => [ 'X-Forwarded-For len 50', 'Host len 15', 'Referrer len 15' ] }, + { 'acl' => [ 'dst_dev01 dst_port 48001', 'dst_dev02 dst_port 48002', 'dst_dev03 dst_port 48003' ] }, + { 'use_backend' => [ 'dev01_webapp if dst_dev01', 'dev02_webapp if dst_dev02', 'dev03_webapp if dst_dev03' ] }, + { 'option' => [ 'httplog', 'http-server-close', 'forwardfor except 127.0.0.1' ] }, + { 'compression' => 'algo gzip', + 'bind-process' => 'all' } + ], + } + end + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind 0.0.0.0:48001-48003 \n mode http\n reqadd X-Forwarded-Proto:\\ https\n default_backend dev00_webapp\n capture request header X-Forwarded-For len 50\n capture request header Host len 15\n capture request header Referrer len 15\n acl dst_dev01 dst_port 48001\n acl dst_dev02 dst_port 48002\n acl dst_dev03 dst_port 48003\n use_backend dev01_webapp if dst_dev01\n use_backend dev02_webapp if dst_dev02\n use_backend dev03_webapp if dst_dev03\n option httplog\n option http-server-close\n option forwardfor except 127.0.0.1\n bind-process all\n compression algo gzip\n" + ) } + end + # C9950 C9951 C9952 WONTFIX end diff --git a/haproxy/spec/defines/listen_spec.rb b/haproxy/spec/defines/listen_spec.rb index 51ca6c2d6..fbad4b077 100644 --- a/haproxy/spec/defines/listen_spec.rb +++ b/haproxy/spec/defines/listen_spec.rb @@ -241,4 +241,31 @@ ) } end + context "when listen options are specified as an array of hashes" do + let(:params) do + { + :name => 'apache', + :bind => { + '0.0.0.0:48001-48003' => [], + }, + :mode => 'http', + :options => [ + { 'reqadd' => 'X-Forwarded-Proto:\ https' }, + { 'default_backend' => 'dev00_webapp' }, + { 'capture request header' => [ 'X-Forwarded-For len 50', 'Host len 15', 'Referrer len 15' ] }, + { 'acl' => [ 'dst_dev01 dst_port 48001', 'dst_dev02 dst_port 48002', 'dst_dev03 dst_port 48003' ] }, + { 'use_backend' => [ 'dev01_webapp if dst_dev01', 'dev02_webapp if dst_dev02', 'dev03_webapp if dst_dev03' ] }, + { 'option' => [ 'httplog', 'http-server-close', 'forwardfor except 127.0.0.1' ] }, + { 'compression' => 'algo gzip', + 'bind-process' => 'all' } + ], + } + end + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind 0.0.0.0:48001-48003 \n mode http\n reqadd X-Forwarded-Proto:\\ https\n default_backend dev00_webapp\n capture request header X-Forwarded-For len 50\n capture request header Host len 15\n capture request header Referrer len 15\n acl dst_dev01 dst_port 48001\n acl dst_dev02 dst_port 48002\n acl dst_dev03 dst_port 48003\n use_backend dev01_webapp if dst_dev01\n use_backend dev02_webapp if dst_dev02\n use_backend dev03_webapp if dst_dev03\n option httplog\n option http-server-close\n option forwardfor except 127.0.0.1\n bind-process all\n compression algo gzip\n" + ) } + end + end diff --git a/haproxy/templates/fragments/_options.erb b/haproxy/templates/fragments/_options.erb index 52ba2d8f4..a61f238ab 100644 --- a/haproxy/templates/fragments/_options.erb +++ b/haproxy/templates/fragments/_options.erb @@ -1,5 +1,19 @@ +<% if @options.is_a?(Hash) -%> <% @options.sort.each do |key, val| -%> <% Array(val).each do |item| -%> <%= key %> <%= item %> <% end -%> <% end -%> +<% elsif @options.is_a?(Array) -%> +<%# Iterate over array elements; each element is a hash (containing key-value -%> +<%# pairs); in case a hash contains more than one key-value pair the hash is -%> +<%# sorted by key name before outputting the key name (= option name) and its -%> +<%# value (or values, one per line) -%> +<% @options.each do |option| -%> +<% option.sort.map do |key, val| -%> +<% Array(val).each do |item| -%> + <%= key %> <%= item %> +<% end -%> +<% end -%> +<% end -%> +<% end -%> diff --git a/heat/.fixtures.yml b/heat/.fixtures.yml index e3874587c..d31679dfa 100644 --- a/heat/.fixtures.yml +++ b/heat/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'ref': '1.2.1' 'keystone': 'git://github.com/stackforge/puppet-keystone.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' 'nova': 'git://github.com/stackforge/puppet-nova.git' diff --git a/heat/LICENSE b/heat/LICENSE index dd5b3a58a..88a11a0e7 100644 --- a/heat/LICENSE +++ b/heat/LICENSE @@ -1,174 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2012 OpenStack Foundation - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +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 - 1. Definitions. + http://www.apache.org/licenses/LICENSE-2.0 - "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. +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/heat/manifests/api.pp b/heat/manifests/api.pp index b90a4e0cb..ee1c2d67c 100644 --- a/heat/manifests/api.pp +++ b/heat/manifests/api.pp @@ -95,7 +95,7 @@ hasrestart => true, require => [Package['heat-common'], Package['heat-api']], - subscribe => Exec['heat-dbsync'], + subscribe => $::heat::subscribe_sync_db, } heat_config { diff --git a/heat/manifests/api_cfn.pp b/heat/manifests/api_cfn.pp index 9738eb415..ab7603f87 100644 --- a/heat/manifests/api_cfn.pp +++ b/heat/manifests/api_cfn.pp @@ -98,7 +98,7 @@ enable => $enabled, hasstatus => true, hasrestart => true, - subscribe => Exec['heat-dbsync'], + subscribe => $::heat::subscribe_sync_db, } heat_config { diff --git a/heat/manifests/api_cloudwatch.pp b/heat/manifests/api_cloudwatch.pp index 8f4a64cd5..034bd3af3 100644 --- a/heat/manifests/api_cloudwatch.pp +++ b/heat/manifests/api_cloudwatch.pp @@ -98,7 +98,7 @@ enable => $enabled, hasstatus => true, hasrestart => true, - subscribe => Exec['heat-dbsync'], + subscribe => $::heat::subscribe_sync_db, } heat_config { diff --git a/heat/manifests/engine.pp b/heat/manifests/engine.pp index 6a62cec02..0dc9dcb2c 100644 --- a/heat/manifests/engine.pp +++ b/heat/manifests/engine.pp @@ -67,6 +67,7 @@ $configure_delegated_roles = true, #DEPRECATED ) { + include ::heat include ::heat::params Heat_config<||> ~> Service['heat-engine'] @@ -77,7 +78,7 @@ ensure => installed, name => $::heat::params::engine_package_name, tag => 'openstack', - notify => Exec['heat-dbsync'], + notify => $::heat::subscribe_sync_db, } if $manage_service { @@ -104,7 +105,7 @@ require => [ File['/etc/heat/heat.conf'], Package['heat-common'], Package['heat-engine']], - subscribe => Exec['heat-dbsync'], + subscribe => $::heat::subscribe_sync_db, } heat_config { diff --git a/heat/manifests/init.pp b/heat/manifests/init.pp index 0d56db64b..c20b3c8c7 100644 --- a/heat/manifests/init.pp +++ b/heat/manifests/init.pp @@ -164,6 +164,10 @@ # (Optional) Enable the stack-abandon feature. # Defaults to undef # +# [*sync_db*] +# (Optional) Run db sync on nodes after connection setting has been set. +# Defaults to true +# # === Deprecated Parameters # # [*mysql_module*] @@ -229,6 +233,7 @@ $region_name = undef, $enable_stack_adopt = undef, $enable_stack_abandon = undef, + $sync_db = true, # Deprecated parameters $mysql_module = undef, $sql_connection = undef, @@ -506,14 +511,17 @@ value => $database_idle_timeout; } - Heat_config['database/connection'] ~> Exec['heat-dbsync'] + if $sync_db { + $subscribe_sync_db = Exec['heat-dbsync'] + Heat_config['database/connection'] ~> Exec['heat-dbsync'] - exec { 'heat-dbsync': - command => $::heat::params::dbsync_command, - path => '/usr/bin', - user => 'heat', - refreshonly => true, - logoutput => on_failure, + exec { 'heat-dbsync': + command => $::heat::params::dbsync_command, + path => '/usr/bin', + user => 'heat', + refreshonly => true, + logoutput => on_failure, + } } } diff --git a/heat/manifests/keystone/domain.pp b/heat/manifests/keystone/domain.pp index 6a6768efa..35f675ff8 100644 --- a/heat/manifests/keystone/domain.pp +++ b/heat/manifests/keystone/domain.pp @@ -41,6 +41,7 @@ include ::heat::params $cmd_evn = [ + "OS_TENANT_NAME=${keystone_tenant}", "OS_USERNAME=${keystone_admin}", "OS_PASSWORD=${keystone_password}", "OS_AUTH_URL=${auth_url}", diff --git a/heat/spec/classes/heat_api_cfn_spec.rb b/heat/spec/classes/heat_api_cfn_spec.rb index 20ffeb31e..6af343a98 100644 --- a/heat/spec/classes/heat_api_cfn_spec.rb +++ b/heat/spec/classes/heat_api_cfn_spec.rb @@ -100,6 +100,17 @@ is_expected.to contain_service('heat-api-cfn').that_subscribes_to('Exec[heat-dbsync]') end end + + context 'with $sync_db set to false in ::heat' do + let :pre_condition do + "class {'heat': sync_db => false}" + end + + it 'configures heat-api-cfn service to not subscribe to the dbsync resource' do + is_expected.to contain_service('heat-api-cfn').that_subscribes_to(nil) + end + end + end diff --git a/heat/spec/classes/heat_api_cloudwatch_spec.rb b/heat/spec/classes/heat_api_cloudwatch_spec.rb index a61caa6e8..7077d87c1 100644 --- a/heat/spec/classes/heat_api_cloudwatch_spec.rb +++ b/heat/spec/classes/heat_api_cloudwatch_spec.rb @@ -100,6 +100,17 @@ is_expected.to contain_service('heat-api-cloudwatch').that_subscribes_to('Exec[heat-dbsync]') end end + + context 'with $sync_db set to false in ::heat' do + let :pre_condition do + "class {'heat': sync_db => false}" + end + + it 'configures heat-api-cloudwatch service to not subscribe to the dbsync resource' do + is_expected.to contain_service('heat-api-cloudwatch').that_subscribes_to(nil) + end + end + end context 'on Debian platforms' do diff --git a/heat/spec/classes/heat_api_spec.rb b/heat/spec/classes/heat_api_spec.rb index 32ccb7552..91589ff1c 100644 --- a/heat/spec/classes/heat_api_spec.rb +++ b/heat/spec/classes/heat_api_spec.rb @@ -103,6 +103,16 @@ is_expected.to contain_service('heat-api').that_subscribes_to('Exec[heat-dbsync]') end end + + context 'with $sync_db set to false in ::heat' do + let :pre_condition do + "class {'heat': sync_db => false}" + end + + it 'configures heat-api service to not subscribe to the dbsync resource' do + is_expected.to contain_service('heat-api').that_subscribes_to(nil) + end + end end context 'on Debian platforms' do diff --git a/heat/spec/classes/heat_engine_spec.rb b/heat/spec/classes/heat_engine_spec.rb index 495d088d8..fad0c8164 100644 --- a/heat/spec/classes/heat_engine_spec.rb +++ b/heat/spec/classes/heat_engine_spec.rb @@ -99,6 +99,21 @@ :subscribe => 'Exec[heat-dbsync]' ) } end + context 'with $sync_db set to false in ::heat' do + let :pre_condition do + "class {'heat': sync_db => false}" + end + + it 'configures heat-engine service to not subscribe to the dbsync resource' do + is_expected.to contain_service('heat-engine').that_subscribes_to(nil) + end + + it 'configures the heat-engine package to not be notified by the dbsync resource ' do + is_expected.to contain_package('heat-engine').with( + :notify => nil, + ) + end + end end context 'on Debian platforms' do diff --git a/heat/spec/classes/heat_keystone_domain_spec.rb b/heat/spec/classes/heat_keystone_domain_spec.rb index 81c1d0904..0eba85d82 100644 --- a/heat/spec/classes/heat_keystone_domain_spec.rb +++ b/heat/spec/classes/heat_keystone_domain_spec.rb @@ -38,6 +38,7 @@ :require => 'Package[heat-common]', :logoutput => 'on_failure', :environment => [ + "OS_TENANT_NAME=#{params[:keystone_tenant]}", "OS_USERNAME=#{params[:keystone_admin]}", "OS_PASSWORD=#{params[:keystone_password]}", "OS_AUTH_URL=#{params[:auth_url]}", diff --git a/horizon/.fixtures.yml b/horizon/.fixtures.yml index eb613b734..4b00834e8 100644 --- a/horizon/.fixtures.yml +++ b/horizon/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: 'apache': 'git://github.com/puppetlabs/puppetlabs-apache.git' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'ref': '1.2.1' 'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git' symlinks: "horizon": "#{source_dir}" diff --git a/horizon/Gemfile b/horizon/Gemfile index 748d075cb..65c29c4ef 100644 --- a/horizon/Gemfile +++ b/horizon/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' group :development, :test do gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-puppet', '~> 2.0.0', :require => false gem 'puppet-lint', '~> 1.1.0' gem 'metadata-json-lint' @@ -16,9 +17,6 @@ group :development, :test do gem 'puppet-lint-variable_contains_upcase' gem 'puppet-lint-numericvariable' - gem 'rspec-puppet', '~> 1.0.1' - gem 'rake', '10.1.1' - gem 'rspec', '< 2.99' gem 'json' gem 'webmock' end diff --git a/horizon/LICENSE b/horizon/LICENSE index 8961ce8a6..88a11a0e7 100644 --- a/horizon/LICENSE +++ b/horizon/LICENSE @@ -1,6 +1,4 @@ -Copyright (C) 2012 Puppet Labs Inc - -Puppet Labs can be contacted at: info@puppetlabs.com +Copyright 2012 OpenStack Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/horizon/manifests/init.pp b/horizon/manifests/init.pp index 246f4a107..a9c00c443 100644 --- a/horizon/manifests/init.pp +++ b/horizon/manifests/init.pp @@ -118,6 +118,11 @@ # security groups. Defaults to True. # 'enable_vpn': Boolean to enable or disable Neutron's VPNaaS feature. # Defaults to False. +# 'enable_distributed_router': Boolean to enable or disable Neutron +# distributed virtual router (DVR) feature in the Router panel. +# Defaults to False. +# 'enable_ha_router': Enable or disable HA (High Availability) mode in +# Neutron virtual router in the Router panel. Defaults to False. # 'profile_support': A string indiciating which plugin-specific # profiles to enable. Defaults to 'None', other options include # 'cisco'. @@ -255,12 +260,14 @@ # be merged with user-provided options when the local_settings.py.erb # template is interpolated. $neutron_defaults = { - 'enable_lb' => false, - 'enable_firewall' => false, - 'enable_quotas' => true, - 'enable_security_group' => true, - 'enable_vpn' => false, - 'profile_support' => 'None', + 'enable_lb' => false, + 'enable_firewall' => false, + 'enable_quotas' => true, + 'enable_security_group' => true, + 'enable_vpn' => false, + 'enable_distributed_router' => false, + 'enable_ha_router' => false, + 'profile_support' => 'None', } Service <| title == 'memcached' |> -> Class['horizon'] diff --git a/horizon/spec/classes/horizon_init_spec.rb b/horizon/spec/classes/horizon_init_spec.rb index c38caf12d..4e18df81f 100644 --- a/horizon/spec/classes/horizon_init_spec.rb +++ b/horizon/spec/classes/horizon_init_spec.rb @@ -25,20 +25,20 @@ context 'with default parameters' do it { - should contain_package('python-lesscpy').with_ensure('present') - should contain_package('horizon').with( + is_expected.to contain_package('python-lesscpy').with_ensure('present') + is_expected.to contain_package('horizon').with( :ensure => 'present', :tag => 'openstack' ) } - it { should contain_exec('refresh_horizon_django_cache').with({ + it { is_expected.to contain_exec('refresh_horizon_django_cache').with({ :command => '/usr/share/openstack-dashboard/manage.py compress', :refreshonly => true, })} - it { should contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') } + it { is_expected.to contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') } it 'configures apache' do - should contain_class('horizon::wsgi::apache').with({ + is_expected.to contain_class('horizon::wsgi::apache').with({ :servername => 'some.host.tld', :listen_ssl => false, :servername => 'some.host.tld', @@ -47,7 +47,7 @@ end it 'generates local_settings.py' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ 'DEBUG = False', "ALLOWED_HOSTS = ['*', ]", "SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'", @@ -60,6 +60,8 @@ " 'enable_quotas': True,", " 'enable_security_group': True,", " 'enable_vpn': False,", + " 'enable_distributed_router': False,", + " 'enable_ha_router': False,", 'API_RESULT_LIMIT = 1000', "LOGIN_URL = '#{platforms_params[:root_url]}/auth/login/'", "LOGOUT_URL = '#{platforms_params[:root_url]}/auth/logout/'", @@ -69,13 +71,13 @@ ]) # From internals of verify_contents, get the contents to check for absence of a line - content = subject.resource('concat::fragment', 'local_settings.py').send(:parameters)[:content] + content = catalogue.resource('concat::fragment', 'local_settings.py').send(:parameters)[:content] # With default options, should _not_ have a line to configure SESSION_ENGINE - content.should_not match(/^SESSION_ENGINE/) + expect(content).not_to match(/^SESSION_ENGINE/) end - it { should_not contain_file(params[:file_upload_temp_dir]) } + it { is_expected.not_to contain_file(params[:file_upload_temp_dir]) } end context 'with overridden parameters' do @@ -92,14 +94,15 @@ :compress_offline => false, :hypervisor_options => {'can_set_mount_point' => false, 'can_set_password' => true }, :cinder_options => {'enable_backup' => true }, - :neutron_options => {'enable_lb' => true, 'enable_firewall' => true, 'enable_quotas' => false, 'enable_security_group' => false, 'enable_vpn' => true, 'profile_support' => 'cisco' }, + :neutron_options => {'enable_lb' => true, 'enable_firewall' => true, 'enable_quotas' => false, 'enable_security_group' => false, 'enable_vpn' => true, + 'enable_distributed_router' => false, 'enable_ha_router' => false, 'profile_support' => 'cisco', }, :file_upload_temp_dir => '/var/spool/horizon', :secure_cookies => true }) end it 'generates local_settings.py' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ 'DEBUG = True', "ALLOWED_HOSTS = ['*', ]", 'CSRF_COOKIE_SECURE = True', @@ -126,9 +129,9 @@ ]) end - it { should_not contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') } + it { is_expected.not_to contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') } - it { should contain_file(params[:file_upload_temp_dir]) } + it { is_expected.to contain_file(params[:file_upload_temp_dir]) } end context 'with overridden parameters and cache_server_ip array' do @@ -139,12 +142,12 @@ end it 'generates local_settings.py' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ " 'LOCATION': [ '10.0.0.1:11211','10.0.0.2:11211', ],", ]) end - it { should contain_exec('refresh_horizon_django_cache') } + it { is_expected.to contain_exec('refresh_horizon_django_cache') } end context 'with vhost_extra_params' do @@ -155,7 +158,7 @@ end it 'configures apache' do - should contain_class('horizon::wsgi::apache').with({ + is_expected.to contain_class('horizon::wsgi::apache').with({ :extra_params => { 'add_listen' => false }, }) end @@ -174,7 +177,7 @@ end it 'configures apache' do - should contain_class('horizon::wsgi::apache').with({ + is_expected.to contain_class('horizon::wsgi::apache').with({ :bind_address => nil, :listen_ssl => true, :horizon_cert => '/etc/pki/tls/certs/httpd.crt', @@ -190,7 +193,7 @@ end it 'does not configure apache' do - should_not contain_class('horizon::wsgi::apache') + is_expected.not_to contain_class('horizon::wsgi::apache') end end @@ -205,7 +208,7 @@ end it 'AVAILABLE_REGIONS is configured' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ "AVAILABLE_REGIONS = [", " ('http://region-1.example.com:5000/v2.0', 'Region-1'),", " ('http://region-2.example.com:5000/v2.0', 'Region-2'),", @@ -227,7 +230,7 @@ end it 'POLICY_FILES_PATH and POLICY_FILES are configured' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ "POLICY_FILES_PATH = '/opt/openstack-dashboard'", "POLICY_FILES = {", " 'compute': 'nova_policy.json',", @@ -248,7 +251,7 @@ end it 'uses the custom local_settings.py template' do - verify_concat_fragment_contents(subject, 'local_settings.py', [ + verify_concat_fragment_contents(catalogue, 'local_settings.py', [ '# Custom local_settings.py', 'DEBUG = True', "HORIZON_CONFIG = {", @@ -277,7 +280,7 @@ }) end - it { should_not contain_file(params[:file_upload_temp_dir]) } + it { is_expected.not_to contain_file(params[:file_upload_temp_dir]) } end end diff --git a/horizon/spec/classes/horizon_wsgi_apache_spec.rb b/horizon/spec/classes/horizon_wsgi_apache_spec.rb index 7a7b9ef15..90ba62397 100644 --- a/horizon/spec/classes/horizon_wsgi_apache_spec.rb +++ b/horizon/spec/classes/horizon_wsgi_apache_spec.rb @@ -29,13 +29,13 @@ context 'with default parameters' do it 'configures apache' do - should contain_class('horizon::params') - should contain_class('apache') - should contain_class('apache::mod::wsgi') - should contain_service('httpd').with_name(platforms_params[:http_service]) - should contain_file(platforms_params[:httpd_config_file]) - should contain_package('horizon').with_ensure('present') - should contain_apache__vhost('horizon_vhost').with( + is_expected.to contain_class('horizon::params') + is_expected.to contain_class('apache') + is_expected.to contain_class('apache::mod::wsgi') + is_expected.to contain_service('httpd').with_name(platforms_params[:http_service]) + is_expected.to contain_file(platforms_params[:httpd_config_file]) + is_expected.to contain_package('horizon').with_ensure('present') + is_expected.to contain_apache__vhost('horizon_vhost').with( 'servername' => 'some.host.tld', 'access_log_file' => 'horizon_access.log', 'error_log_file' => 'horizon_error.log', @@ -62,13 +62,13 @@ end it 'configures apache' do - should contain_class('horizon::params') - should contain_class('apache') - should contain_class('apache::mod::wsgi') - should contain_service('httpd').with_name(platforms_params[:http_service]) - should contain_file(platforms_params[:httpd_config_file]) - should contain_package('horizon').with_ensure('present') - should contain_apache__vhost('horizon_vhost').with( + is_expected.to contain_class('horizon::params') + is_expected.to contain_class('apache') + is_expected.to contain_class('apache::mod::wsgi') + is_expected.to contain_service('httpd').with_name(platforms_params[:http_service]) + is_expected.to contain_file(platforms_params[:httpd_config_file]) + is_expected.to contain_package('horizon').with_ensure('present') + is_expected.to contain_apache__vhost('horizon_vhost').with( 'servername' => 'some.host.tld', 'access_log_file' => 'horizon_access.log', 'error_log_file' => 'horizon_error.log', @@ -100,9 +100,9 @@ context 'with required parameters' do it 'configures apache for SSL' do - should contain_class('apache::mod::ssl') + is_expected.to contain_class('apache::mod::ssl') end - it { should contain_apache__vhost('horizon_ssl_vhost').with( + it { is_expected.to contain_apache__vhost('horizon_ssl_vhost').with( 'servername' => 'some.host.tld', 'access_log_file' => 'horizon_ssl_access.log', 'error_log_file' => 'horizon_ssl_error.log', @@ -121,7 +121,7 @@ 'wsgi_script_aliases' => { platforms_params[:root_url] => '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi' } )} - it { should contain_apache__vhost('horizon_vhost').with( + it { is_expected.to contain_apache__vhost('horizon_vhost').with( 'servername' => 'some.host.tld', 'access_log_file' => 'horizon_access.log', 'error_log_file' => 'horizon_error.log', @@ -167,7 +167,7 @@ end it 'configures apache' do - should contain_apache__vhost('horizon_vhost').with( + is_expected.to contain_apache__vhost('horizon_vhost').with( 'add_listen' => false, 'docroot' => '/tmp' ) @@ -201,7 +201,7 @@ it_behaves_like 'apache for horizon' it { - should contain_class('apache::mod::wsgi').with(:wsgi_socket_prefix => '/var/run/wsgi') + is_expected.to contain_class('apache::mod::wsgi').with(:wsgi_socket_prefix => '/var/run/wsgi') } end diff --git a/horizon/spec/shared_examples.rb b/horizon/spec/shared_examples.rb index 51e11c0ba..fec0eacc9 100644 --- a/horizon/spec/shared_examples.rb +++ b/horizon/spec/shared_examples.rb @@ -1,5 +1,5 @@ shared_examples_for "a Puppet::Error" do |description| it "with message matching #{description.inspect}" do - expect { subject }.to raise_error(Puppet::Error, description) + expect { is_expected.to have_class_count(1) }.to raise_error(Puppet::Error, description) end end diff --git a/horizon/spec/spec_helper.rb b/horizon/spec/spec_helper.rb index b3bca421a..605a8ad05 100644 --- a/horizon/spec/spec_helper.rb +++ b/horizon/spec/spec_helper.rb @@ -8,5 +8,5 @@ def verify_concat_fragment_contents(subject, title, expected_lines) content = subject.resource('concat::fragment', title).send(:parameters)[:content] - (content.split("\n") & expected_lines).should == expected_lines + expect(content.split("\n") & expected_lines).to eq(expected_lines) end diff --git a/horizon/spec/unit/puppet/parser/functions/os_any2array_spec.rb b/horizon/spec/unit/puppet/parser/functions/os_any2array_spec.rb index dd5bbe2c3..70a993981 100644 --- a/horizon/spec/unit/puppet/parser/functions/os_any2array_spec.rb +++ b/horizon/spec/unit/puppet/parser/functions/os_any2array_spec.rb @@ -5,51 +5,51 @@ let(:scope) { PuppetlabsSpec::PuppetInternals.scope } it "should exist" do - Puppet::Parser::Functions.function("os_any2array").should == "function_os_any2array" + expect(Puppet::Parser::Functions.function("os_any2array")).to eq("function_os_any2array") end it "should return an empty array if there is less than 1 argument" do result = scope.function_os_any2array([]) - result.should(eq([])) + expect(result).to(eq([])) end it "should convert boolean true to [ true ] " do result = scope.function_os_any2array([true]) - result.should(eq([true])) + expect(result).to(eq([true])) end it "should convert one object to [object]" do result = scope.function_os_any2array(['one']) - result.should(eq(['one'])) + expect(result).to(eq(['one'])) end it "should convert multiple objects to [objects]" do result = scope.function_os_any2array(['one', 'two']) - result.should(eq(['one', 'two'])) + expect(result).to(eq(['one', 'two'])) end it "should return empty array it was called with" do result = scope.function_os_any2array([[]]) - result.should(eq([])) + expect(result).to(eq([])) end it "should return one-member array it was called with" do result = scope.function_os_any2array([['string']]) - result.should(eq(['string'])) + expect(result).to(eq(['string'])) end it "should return multi-member array it was called with" do result = scope.function_os_any2array([['one', 'two']]) - result.should(eq(['one', 'two'])) + expect(result).to(eq(['one', 'two'])) end it "should return members of a hash it was called with" do result = scope.function_os_any2array([{ 'key' => 'value' }]) - result.should(eq(['key', 'value'])) + expect(result).to(eq(['key', 'value'])) end it "should return an empty array if it was called with an empty hash" do result = scope.function_os_any2array([{ }]) - result.should(eq([])) + expect(result).to(eq([])) end end diff --git a/horizon/templates/local_settings.py.erb b/horizon/templates/local_settings.py.erb index dbeb9e880..944c00ea4 100644 --- a/horizon/templates/local_settings.py.erb +++ b/horizon/templates/local_settings.py.erb @@ -202,6 +202,8 @@ OPENSTACK_NEUTRON_NETWORK = { 'enable_quotas': <%= @neutron_options['enable_quotas'].to_s.capitalize %>, 'enable_security_group': <%= @neutron_options['enable_security_group'].to_s.capitalize %>, 'enable_vpn': <%= @neutron_options['enable_vpn'].to_s.capitalize %>, + 'enable_distributed_router': <%= @neutron_options['enable_distributed_router'].to_s.capitalize %>, + 'enable_ha_router': <%= @neutron_options['enable_ha_router'].to_s.capitalize %>, # The profile_support option is used to detect if an externa lrouter can be # configured via the dashboard. When using specific plugins the # profile_support can be turned on if needed. diff --git a/keystone/.fixtures.yml b/keystone/.fixtures.yml index 066d4105e..73f11ff6c 100644 --- a/keystone/.fixtures.yml +++ b/keystone/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: 'apache': 'git://github.com/puppetlabs/puppetlabs-apache.git' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'ref': '1.2.1' 'apt': 'git://github.com/puppetlabs/puppetlabs-apt.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' 'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git' diff --git a/keystone/LICENSE b/keystone/LICENSE index 0bc44c17d..88a11a0e7 100644 --- a/keystone/LICENSE +++ b/keystone/LICENSE @@ -1,8 +1,4 @@ -Puppet Labs Keystone Module - Puppet module for managing Keystone - -Copyright (C) 2012 Puppet Labs Inc - -Puppet Labs can be contacted at: info@puppetlabs.com +Copyright 2012 OpenStack Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/keystone/examples/apache_with_paths.pp b/keystone/examples/apache_with_paths.pp index ce61bea72..8b0fc699c 100644 --- a/keystone/examples/apache_with_paths.pp +++ b/keystone/examples/apache_with_paths.pp @@ -38,8 +38,8 @@ password => 'ChangeMe', } class { '::keystone::endpoint': - public_url => "https://${::fqdn}:443/main/", - admin_address => "https://${::fqdn}:443/admin/", + public_url => "https://${::fqdn}:443/main/", + admin_url => "https://${::fqdn}:443/admin/", } keystone_config { 'ssl/enable': ensure => absent } diff --git a/keystone/lib/puppet/provider/keystone.rb b/keystone/lib/puppet/provider/keystone.rb index b398a8e30..b5112290c 100644 --- a/keystone/lib/puppet/provider/keystone.rb +++ b/keystone/lib/puppet/provider/keystone.rb @@ -24,10 +24,10 @@ def keystone_request(service, action, object, credentials, error, *properties) def self.keystone_request(service, action, object, credentials, error, *properties) credentials = { - 'token' => get_admin_token, - 'auth_url' => get_admin_endpoint, + 'token' => get_admin_token, + 'url' => get_admin_endpoint, } - raise error unless (credentials['token'] && credentials['auth_url']) + raise error unless (credentials['token'] && credentials['url']) auth_args = token_auth_args(credentials) args = [object, properties, auth_args].flatten.compact authenticate_request(service, action, args) diff --git a/keystone/lib/puppet/provider/keystone_user/openstack.rb b/keystone/lib/puppet/provider/keystone_user/openstack.rb index 6dcf99586..6c8d04aa2 100644 --- a/keystone/lib/puppet/provider/keystone_user/openstack.rb +++ b/keystone/lib/puppet/provider/keystone_user/openstack.rb @@ -62,6 +62,8 @@ def password return nil if resource[:password] == nil # if the user is disabled then the password can't be changed return resource[:password] if resource[:enabled] == :false + # if replacing password is disabled, then don't change it + return resource[:password] if resource[:replace_password] == :false # we can't get the value of the password but we can test to see if the one we know # about works, if it doesn't then return nil, causing it to be reset endpoint = nil @@ -157,6 +159,14 @@ def tenant end end + def replace_password + instance(resource[:name])[:replace_password] + end + + def replace_password=(value) + @property_flush[:replace_password] = value + end + def email=(value) @property_flush[:email] = value end diff --git a/keystone/lib/puppet/type/keystone_user.rb b/keystone/lib/puppet/type/keystone_user.rb index e27f14cd6..ce3a5623d 100644 --- a/keystone/lib/puppet/type/keystone_user.rb +++ b/keystone/lib/puppet/type/keystone_user.rb @@ -61,6 +61,14 @@ def should_to_s( newvalue ) end end + newparam(:replace_password) do + newvalues(/(t|T)rue/, /(f|F)alse/, true, false) + defaultto(true) + munge do |value| + value.to_s.downcase.to_sym + end + end + autorequire(:keystone_tenant) do self[:tenant] end diff --git a/keystone/manifests/init.pp b/keystone/manifests/init.pp index cf27b1c0c..4750e165d 100644 --- a/keystone/manifests/init.pp +++ b/keystone/manifests/init.pp @@ -339,6 +339,10 @@ # (optional) The number of worker processes to serve the public WSGI application. # Defaults to max($::processorcount, 2) # +# [*sync_db*] +# (Optional) Run db sync on the node. +# Defaults to true +# # == Dependencies # None # @@ -438,6 +442,7 @@ $max_token_size = undef, $admin_workers = max($::processorcount, 2), $public_workers = max($::processorcount, 2), + $sync_db = true, # DEPRECATED PARAMETERS $mysql_module = undef, $compute_port = undef, @@ -805,7 +810,7 @@ fail('Invalid service_name. Either keystone/openstack-keystone for running as a standalone service, or httpd for being run by a httpd server') } - if $enabled { + if $enabled and $sync_db { include ::keystone::db::sync Class['::keystone::db::sync'] ~> Service[$service_name] } diff --git a/keystone/spec/classes/keystone_spec.rb b/keystone/spec/classes/keystone_spec.rb index f34ff7193..fe2c0033d 100644 --- a/keystone/spec/classes/keystone_spec.rb +++ b/keystone/spec/classes/keystone_spec.rb @@ -457,6 +457,17 @@ it { is_expected.to contain_keystone_config("token/expiration").with_value('3600') } end + describe 'when sync_db is set to false' do + let :params do + { + 'admin_token' => 'service_token', + 'sync_db' => false, + } + end + + it { is_expected.not_to contain_exec('keystone-manage db_sync') } + end + describe 'configure memcache servers if set' do let :params do { diff --git a/keystone/spec/unit/provider/keystone_endpoint/openstack_spec.rb b/keystone/spec/unit/provider/keystone_endpoint/openstack_spec.rb index a0ac7523e..d88f246ea 100644 --- a/keystone/spec/unit/provider/keystone_endpoint/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_endpoint/openstack_spec.rb @@ -16,10 +16,10 @@ :internal_url => 'http://127.0.0.1:5001/v2.0', :admin_url => 'http://127.0.0.1:5002/v2.0', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -35,12 +35,12 @@ describe '#create' do it 'creates an endpoint' do provider.class.stubs(:openstack) - .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" "1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" ') provider.class.stubs(:openstack) - .with('endpoint', 'create', '--format', 'shell', [['bar', '--region', 'foo', '--publicurl', 'http://127.0.0.1:5000/v2.0', '--internalurl', 'http://127.0.0.1:5001/v2.0', '--adminurl', 'http://127.0.0.1:5002/v2.0', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'create', '--format', 'shell', [['bar', '--region', 'foo', '--publicurl', 'http://127.0.0.1:5000/v2.0', '--internalurl', 'http://127.0.0.1:5001/v2.0', '--adminurl', 'http://127.0.0.1:5002/v2.0', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('adminurl="http://127.0.0.1:5002/v2.0" id="3a5c4378981e4112a0d44902a43e16ef" internalurl="http://127.0.0.1:5001/v2.0" @@ -58,12 +58,12 @@ describe '#destroy' do it 'destroys an endpoint' do provider.class.stubs(:openstack) - .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" "1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" ') provider.class.stubs(:openstack) - .with('endpoint', 'delete', [['1cb05cfed7c24279be884ba4f6520262', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'delete', [['1cb05cfed7c24279be884ba4f6520262', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) expect(provider.destroy).to be_nil # We don't really care that it's nil, only that it runs successfully end @@ -74,7 +74,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" "1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" ') @@ -88,7 +88,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"') response = provider.exists? end @@ -100,7 +100,7 @@ describe '#instances' do it 'finds every tenant' do provider.class.stubs(:openstack) - .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('endpoint', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" "1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" ') diff --git a/keystone/spec/unit/provider/keystone_role/openstack_spec.rb b/keystone/spec/unit/provider/keystone_role/openstack_spec.rb index 179574fea..13f877b97 100644 --- a/keystone/spec/unit/provider/keystone_role/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_role/openstack_spec.rb @@ -13,10 +13,10 @@ :name => 'foo', :ensure => 'present', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -32,12 +32,12 @@ describe '#create' do it 'creates a role' do provider.class.stubs(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name" "1cb05cfed7c24279be884ba4f6520262","foo" ') provider.class.stubs(:openstack) - .with('role', 'create', '--format', 'shell', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'create', '--format', 'shell', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('name="foo"') provider.create expect(provider.exists?).to be_truthy @@ -47,10 +47,10 @@ describe '#destroy' do it 'destroys a role' do provider.class.stubs(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name"') provider.class.stubs(:openstack) - .with('role', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.destroy expect(provider.exists?).to be_falsey end @@ -62,7 +62,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name" "1cb05cfed7c24279be884ba4f6520262","foo" ') @@ -76,7 +76,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name"') response = provider.exists? end @@ -88,7 +88,7 @@ describe '#instances' do it 'finds every role' do provider.class.stubs(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name" "1cb05cfed7c24279be884ba4f6520262","foo" ') diff --git a/keystone/spec/unit/provider/keystone_service/openstack_spec.rb b/keystone/spec/unit/provider/keystone_service/openstack_spec.rb index 5b9814f91..622d000d8 100644 --- a/keystone/spec/unit/provider/keystone_service/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_service/openstack_spec.rb @@ -15,10 +15,10 @@ :ensure => 'present', :type => 'foo', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -34,12 +34,12 @@ describe '#create' do it 'creates a service' do provider.class.stubs(:openstack) - .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Type","Description" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo" ') provider.class.stubs(:openstack) - .with('service', 'create', '--format', 'shell', [['foo', '--description', 'foo', '--type', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'create', '--format', 'shell', [['foo', '--description', 'foo', '--type', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('description="foo" enabled="True" id="8f0dd4c0abc44240998fbb3f5089ecbf" @@ -54,10 +54,10 @@ describe '#destroy' do it 'destroys a service' do provider.class.stubs(:openstack) - .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Type","Description"') provider.class.stubs(:openstack) - .with('service', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.destroy expect(provider.exists?).to be_falsey end @@ -69,7 +69,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Type","Description" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo" ') @@ -83,7 +83,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Type","Description"') response = provider.exists? end @@ -95,7 +95,7 @@ describe '#instances' do it 'finds every service' do provider.class.stubs(:openstack) - .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('service', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Type","Description" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo" ') diff --git a/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb b/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb index 11861fc8b..fe7d73b26 100644 --- a/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb @@ -15,10 +15,10 @@ :ensure => 'present', :enabled => 'True', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -34,12 +34,12 @@ describe '#create' do it 'creates a tenant' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo",True ') provider.class.stubs(:openstack) - .with('project', 'create', '--format', 'shell', [['foo', '--enable', '--description', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'create', '--format', 'shell', [['foo', '--enable', '--description', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('description="foo" enabled="True" name="foo" @@ -52,10 +52,10 @@ describe '#destroy' do it 'destroys a tenant' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled"') provider.class.stubs(:openstack) - .with('project', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.destroy expect(provider.exists?).to be_falsey end @@ -67,7 +67,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo",True ') @@ -81,7 +81,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled"') response = provider.exists? end @@ -93,7 +93,7 @@ describe '#instances' do it 'finds every tenant' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo",True ') diff --git a/keystone/spec/unit/provider/keystone_user/openstack_spec.rb b/keystone/spec/unit/provider/keystone_user/openstack_spec.rb index 5b87ca18e..51d1dfce2 100644 --- a/keystone/spec/unit/provider/keystone_user/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_user/openstack_spec.rb @@ -15,10 +15,10 @@ :tenant => 'foo', :email => 'foo@example.com', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -36,12 +36,12 @@ describe '#create' do it 'creates a user' do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True ') provider.class.stubs(:openstack) - .with('user', 'create', '--format', 'shell', [['foo', '--enable', '--password', 'foo', '--project', 'foo', '--email', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'create', '--format', 'shell', [['foo', '--enable', '--password', 'foo', '--project', 'foo', '--email', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('email="foo@example.com" enabled="True" id="12b23f07d4a3448d8189521ab09610b0" @@ -57,10 +57,10 @@ describe '#destroy' do it 'destroys a user' do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled"') provider.class.stubs(:openstack) - .with('user', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'delete', [['foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.destroy expect(provider.exists?).to be_falsey end @@ -72,7 +72,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True ') @@ -86,7 +86,7 @@ subject(:response) do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled"') response = provider.exists? end @@ -98,7 +98,7 @@ describe '#instances' do it 'finds every user' do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True ') @@ -110,7 +110,7 @@ describe '#tenant' do it 'gets the tenant with default backend' do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True ') @@ -119,12 +119,12 @@ end it 'gets the tenant with LDAP backend' do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","Email","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","","foo@example.com",True ') provider.class.expects(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","User" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo" ') @@ -136,9 +136,9 @@ context 'when using default backend' do it 'sets the tenant' do provider.class.expects(:openstack) - .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.class.expects(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","User" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo" ') @@ -148,52 +148,52 @@ context 'when using LDAP read-write backend' do it 'sets the tenant when _member_ role exists' do provider.class.expects(:openstack) - .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.class.expects(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('') provider.class.expects(:openstack) - .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.tenant=('bar') end it 'sets the tenant when _member_ role does not exist' do provider.class.expects(:openstack) - .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.class.expects(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('') provider.class.expects(:openstack) - .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .raises(Puppet::ExecutionFailure, 'no such role _member_') provider.class.expects(:openstack) - .with('role', 'create', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'create', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.tenant=('bar') end end context 'when using LDAP read-only backend' do it 'sets the tenant when _member_ role exists' do provider.class.expects(:openstack) - .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .raises(Puppet::ExecutionFailure, 'You are not authorized to perform the requested action: LDAP user update') provider.class.expects(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('') provider.class.expects(:openstack) - .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'show', '--format', 'shell', [['_member_', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.tenant=('bar') end it 'sets the tenant and gets an unexpected exception message' do provider.class.expects(:openstack) - .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'set', [['foo', '--project', 'bar', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .raises(Puppet::ExecutionFailure, 'unknown error message') expect{ provider.tenant=('bar') }.to raise_error(Puppet::ExecutionFailure, /unknown error message/) end @@ -212,10 +212,10 @@ :tenant => 'foo', :email => 'foo@example.com', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'https://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'https://127.0.0.1:5000/v2.0', } } end @@ -250,5 +250,39 @@ password = provider.password expect(password).to eq(nil) end + + describe 'when updating a user with unmanaged password' do + + let(:user_attrs) do + { + :name => 'foo', + :ensure => 'present', + :enabled => 'True', + :password => 'foo', + :replace_password => 'False', + :tenant => 'foo', + :email => 'foo@example.com', + :auth => { + 'username' => 'test', + 'password' => 'abc123', + 'tenant_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', + } + } + end + + let(:resource) do + Puppet::Type::Keystone_user.new(user_attrs) + end + + let :provider do + provider_class.new(resource) + end + + it 'should not try to check password' do + expect(provider.password).to eq('foo') + end + end + end end diff --git a/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb b/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb index f3c35dcf6..1be2bd64f 100644 --- a/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb @@ -14,10 +14,10 @@ :ensure => 'present', :roles => ['foo', 'bar'], :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'foo', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'foo', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -32,12 +32,12 @@ before(:each) do provider.class.stubs(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name" "1cb05cfed7c24279be884ba4f6520262","foo@example.com" ') provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name" "1cb05cfed7c24279be884ba4f6520262","foo" ') @@ -46,15 +46,15 @@ describe '#create' do it 'adds all the roles to the user' do provider.class.stubs(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","User" "1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com" "1cb05cfed7c24279be884ba4f6520263","bar","foo","foo@example.com" ') provider.class.stubs(:openstack) - .with('role', 'add', [['foo', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'add', [['foo', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.class.stubs(:openstack) - .with('role', 'add', [['bar', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'add', [['bar', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.create expect(provider.exists?).to be_truthy end @@ -63,12 +63,12 @@ describe '#destroy' do it 'removes all the roles from a user' do provider.class.stubs(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","User"') provider.class.stubs(:openstack) - .with('role', 'remove', [['foo', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'remove', [['foo', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.class.stubs(:openstack) - .with('role', 'remove', [['bar', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('role', 'remove', [['bar', '--project', 'foo', '--user', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) provider.destroy expect(provider.exists?).to be_falsey end @@ -78,7 +78,7 @@ describe '#exists' do subject(:response) do provider.class.stubs(:openstack) - .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('user role', 'list', '--quiet', '--format', 'csv', [['--project', 'foo', 'foo@example.com', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'foo', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Project","User" "1cb05ed7c24279be884ba4f6520262","foo","foo","foo@example.com" "1cb05ed7c24279be884ba4f6520262","bar","foo","foo@example.com" diff --git a/module-collectd/.gitignore b/module-collectd/.gitignore index 7cc4f8287..00f205494 100644 --- a/module-collectd/.gitignore +++ b/module-collectd/.gitignore @@ -1,5 +1,4 @@ pkg/ -Gemfile.lock .rspec_system *.swp .bundle/ diff --git a/module-collectd/Gemfile.lock b/module-collectd/Gemfile.lock new file mode 100644 index 000000000..3e406d83c --- /dev/null +++ b/module-collectd/Gemfile.lock @@ -0,0 +1,232 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.2.8) + activesupport (4.2.0) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.3.6) + archive-tar-minitar (0.5.2) + autoparse (0.3.3) + addressable (>= 2.3.1) + extlib (>= 0.9.15) + multi_json (>= 1.0.0) + aws-sdk (1.60.2) + aws-sdk-v1 (= 1.60.2) + aws-sdk-v1 (1.60.2) + json (~> 1.4) + nokogiri (>= 1.4.4) + beaker (2.1.0) + aws-sdk (~> 1.57) + docker-api + fission (~> 0.4) + fog (~> 1.25) + google-api-client (~> 0.7) + hocon (~> 0.0.4) + inifile (~> 2.0) + json (~> 1.8) + minitest (~> 5.4) + net-scp (~> 1.2) + net-ssh (~> 2.9) + rbvmomi (~> 1.8) + unf (~> 0.1) + beaker-rspec (4.0.0) + beaker (~> 2.0) + rspec + serverspec (~> 1.0) + specinfra (~> 1.0) + builder (3.2.2) + diff-lcs (1.2.5) + docile (1.1.5) + docker-api (1.17.0) + archive-tar-minitar + excon (>= 0.38.0) + json + excon (0.42.1) + extlib (0.9.16) + facter (2.3.0) + CFPropertyList (~> 2.2.6) + faraday (0.9.0) + multipart-post (>= 1.2, < 3) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.26.0) + fog-atmos + fog-brightbox (~> 0.4) + fog-core (~> 1.27, >= 1.27.1) + fog-ecloud + fog-json + fog-profitbricks + fog-radosgw (>= 0.0.2) + fog-sakuracloud (>= 0.0.4) + fog-softlayer + fog-storm_on_demand + fog-terremark + fog-vmfusion + fog-voxel + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) + nokogiri (~> 1.5, >= 1.5.11) + fog-atmos (0.1.0) + fog-core + fog-xml + fog-brightbox (0.7.1) + fog-core (~> 1.22) + fog-json + inflecto (~> 0.0.2) + fog-core (1.27.2) + builder + excon (~> 0.38) + formatador (~> 0.2) + mime-types + net-scp (~> 1.1) + net-ssh (>= 2.1.3) + fog-ecloud (0.0.2) + fog-core + fog-xml + fog-json (1.0.0) + multi_json (~> 1.0) + fog-profitbricks (0.0.1) + fog-core + fog-xml + nokogiri + fog-radosgw (0.0.3) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-sakuracloud (0.1.1) + fog-core + fog-json + fog-softlayer (0.3.26) + fog-core + fog-json + fog-storm_on_demand (0.1.0) + fog-core + fog-json + fog-terremark (0.0.3) + fog-core + fog-xml + fog-vmfusion (0.0.1) + fission + fog-core + fog-voxel (0.0.2) + fog-core + fog-xml + fog-xml (0.1.1) + fog-core + nokogiri (~> 1.5, >= 1.5.11) + formatador (0.2.5) + google-api-client (0.8.1.1) + activesupport (>= 3.2) + addressable (~> 2.3) + autoparse (~> 0.3) + extlib (~> 0.9) + faraday (~> 0.9) + launchy (~> 2.4) + multi_json (~> 1.10) + retriable (~> 1.4) + signet (~> 0.6) + hiera (1.3.4) + json_pure + highline (1.6.21) + hocon (0.0.6) + i18n (0.7.0) + inflecto (0.0.2) + inifile (2.0.2) + ipaddress (0.8.0) + json (1.8.1) + json_pure (1.8.1) + jwt (1.2.0) + launchy (2.4.3) + addressable (~> 2.3) + metaclass (0.0.4) + mime-types (2.4.3) + mini_portile (0.6.1) + minitest (5.5.0) + mocha (1.1.0) + metaclass (~> 0.0.1) + multi_json (1.10.1) + multipart-post (2.0.0) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (2.9.1) + nokogiri (1.6.5) + mini_portile (~> 0.6.0) + puppet (3.7.3) + facter (> 1.6, < 3) + hiera (~> 1.0) + json_pure + puppet-lint (1.1.0) + puppet-syntax (1.4.0) + rake + puppet_facts (0.2.1) + puppetlabs_spec_helper (0.8.2) + mocha + puppet-lint + puppet-syntax + rake + rspec + rspec-puppet + rake (10.4.2) + rbvmomi (1.8.2) + builder + nokogiri (>= 1.4.1) + trollop + retriable (1.4.1) + rspec (2.99.0) + rspec-core (~> 2.99.0) + rspec-expectations (~> 2.99.0) + rspec-mocks (~> 2.99.0) + rspec-core (2.99.2) + rspec-expectations (2.99.2) + diff-lcs (>= 1.1.3, < 2.0) + rspec-its (1.0.1) + rspec-core (>= 2.99.0.beta1) + rspec-expectations (>= 2.99.0.beta1) + rspec-mocks (2.99.2) + rspec-puppet (1.0.1) + rspec + serverspec (1.16.0) + highline + net-ssh + rspec (~> 2.99) + rspec-its + specinfra (~> 1.27) + signet (0.6.0) + addressable (~> 2.3) + extlib (~> 0.9) + faraday (~> 0.9) + jwt (~> 1.0) + multi_json (~> 1.10) + simplecov (0.9.1) + docile (~> 1.1.0) + multi_json (~> 1.0) + simplecov-html (~> 0.8.0) + simplecov-html (0.8.0) + specinfra (1.27.5) + thread_safe (0.3.4) + trollop (2.0) + tzinfo (1.2.2) + thread_safe (~> 0.1) + unf (0.1.4) + unf_ext + unf_ext (0.0.6) + +PLATFORMS + ruby + +DEPENDENCIES + beaker-rspec + facter + json + puppet + puppet-lint + puppet_facts + puppetlabs_spec_helper + rake + rspec-puppet + serverspec + simplecov diff --git a/module-collectd/README.md b/module-collectd/README.md index d540a6acc..03b611fea 100644 --- a/module-collectd/README.md +++ b/module-collectd/README.md @@ -908,6 +908,10 @@ class { 'collectd::plugin::zfs_arc': See metadata.json for supported platforms +##Known issues + +Some plugins will need two runs of Puppet to fully generate the configuration for collectd. See [this issue](https://github.com/pdxcat/puppet-module-collectd/issues/162). + ##Development ### Running tests @@ -923,3 +927,13 @@ bundle exec rake lint bundle exec rake validate bundle exec rake spec SPEC_OPTS='--format documentation' ``` + +### Version scoping + +Some plugins or some options in plugins are only available for recent versions of collectd. + +This module shall not use unsupported configuration directives. Look at [templates/loadplugin.conf.erb](https://github.com/pdxcat/puppet-module-collectd/blob/master/templates/loadplugin.conf.erb) for a hands-on example. + +Please make use of the search by branch/tags on the collectd github to see when a function has been first released. + +Reading the [collectd.conf.pod](https://github.com/collectd/collectd/blob/master/src/collectd.conf.pod) file is good, validating the presence of the code in the .c files is even better. \ No newline at end of file diff --git a/module-collectd/Rakefile b/module-collectd/Rakefile index 902062317..a64429cae 100644 --- a/module-collectd/Rakefile +++ b/module-collectd/Rakefile @@ -1,7 +1,7 @@ require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-lint/tasks/puppet-lint' -PuppetLint.configuration.fail_on_warnings +PuppetLint.configuration.fail_on_warnings = true PuppetLint.configuration.send('disable_80chars') PuppetLint.configuration.send('disable_class_inherits_from_params_class') PuppetLint.configuration.send('disable_class_parameter_defaults') diff --git a/module-collectd/manifests/plugin/curl_json.pp b/module-collectd/manifests/plugin/curl_json.pp index b571b4a1f..f571bb9c4 100644 --- a/module-collectd/manifests/plugin/curl_json.pp +++ b/module-collectd/manifests/plugin/curl_json.pp @@ -3,6 +3,7 @@ $url, $instance, $keys, + $ensure = present, $user = undef, $password = undef, $order = '10', diff --git a/module-collectd/manifests/plugin/exec.pp b/module-collectd/manifests/plugin/exec.pp index 873dac9f5..f9317db79 100644 --- a/module-collectd/manifests/plugin/exec.pp +++ b/module-collectd/manifests/plugin/exec.pp @@ -16,8 +16,8 @@ # This is deprecated file naming ensuring old style file removed, and should be removed in next major relese file { "${name}.load-deprecated": - path => "${conf_dir}/${name}.conf", ensure => absent, + path => "${conf_dir}/${name}.conf", } # End deprecation diff --git a/module-collectd/manifests/plugin/genericjmx/connection.pp b/module-collectd/manifests/plugin/genericjmx/connection.pp index 23d475acb..b08432e37 100644 --- a/module-collectd/manifests/plugin/genericjmx/connection.pp +++ b/module-collectd/manifests/plugin/genericjmx/connection.pp @@ -1,11 +1,11 @@ # https://collectd.org/wiki/index.php/Plugin:GenericJMX define collectd::plugin::genericjmx::connection ( - $host = $name, + $collect, $service_url, + $host = $name, $user = undef, $password = undef, $instance_prefix = undef, - $collect, ) { include collectd::plugin::genericjmx concat::fragment { "collectd_plugin_genericjmx_conf_${name}": diff --git a/module-collectd/manifests/plugin/genericjmx/mbean.pp b/module-collectd/manifests/plugin/genericjmx/mbean.pp index 68f0e1435..98aa2d33d 100644 --- a/module-collectd/manifests/plugin/genericjmx/mbean.pp +++ b/module-collectd/manifests/plugin/genericjmx/mbean.pp @@ -1,9 +1,9 @@ # https://collectd.org/wiki/index.php/Plugin:GenericJMX define collectd::plugin::genericjmx::mbean ( $object_name, + $values, $instance_prefix = undef, $instance_from = undef, - $values, ) { include collectd::plugin::genericjmx validate_array($values) diff --git a/module-collectd/manifests/plugin/mysql.pp b/module-collectd/manifests/plugin/mysql.pp index 4dcd03895..f8573a9bd 100644 --- a/module-collectd/manifests/plugin/mysql.pp +++ b/module-collectd/manifests/plugin/mysql.pp @@ -1,6 +1,7 @@ # MySQL plugin # https://collectd.org/wiki/index.php/Plugin:MySQL class collectd::plugin::mysql ( + $ensure = present, $interval = undef, ){ diff --git a/module-collectd/manifests/plugin/mysql/database.pp b/module-collectd/manifests/plugin/mysql/database.pp index 9216e9a02..e736ea1e5 100644 --- a/module-collectd/manifests/plugin/mysql/database.pp +++ b/module-collectd/manifests/plugin/mysql/database.pp @@ -28,7 +28,7 @@ file { "${name}.conf": ensure => $ensure, path => "${conf_dir}/mysql-${name}.conf", - mode => '0644', + mode => '0640', owner => 'root', group => $collectd::params::root_group, content => template('collectd/mysql-database.conf.erb'), diff --git a/module-collectd/manifests/plugin/network/server.pp b/module-collectd/manifests/plugin/network/server.pp index 8e5aad589..c271b5e31 100644 --- a/module-collectd/manifests/plugin/network/server.pp +++ b/module-collectd/manifests/plugin/network/server.pp @@ -6,6 +6,7 @@ $port = undef, $securitylevel = undef, $interface = undef, + $forward = undef, ) { include collectd::params include collectd::plugin::network diff --git a/module-collectd/manifests/plugin/ping.pp b/module-collectd/manifests/plugin/ping.pp index 88c4411f2..eee249bc2 100644 --- a/module-collectd/manifests/plugin/ping.pp +++ b/module-collectd/manifests/plugin/ping.pp @@ -1,6 +1,7 @@ # See http://collectd.org/documentation/manpages/collectd.conf.5.shtml#plugin_ping define collectd::plugin::ping ( $hosts, + $ensure = present, $interval = undef, $timeout = undef, $ttl = undef, diff --git a/module-collectd/manifests/plugin/snmp/data.pp b/module-collectd/manifests/plugin/snmp/data.pp index 116221edb..097e17255 100644 --- a/module-collectd/manifests/plugin/snmp/data.pp +++ b/module-collectd/manifests/plugin/snmp/data.pp @@ -1,10 +1,10 @@ # https://collectd.org/wiki/index.php/Plugin:SNMP define collectd::plugin::snmp::data ( - $ensure = present, - $type, - $table = false, $instance, + $type, $values, + $ensure = present, + $table = false, ) { include collectd include collectd::plugin::snmp diff --git a/module-collectd/manifests/plugin/snmp/host.pp b/module-collectd/manifests/plugin/snmp/host.pp index 698163139..03495f723 100644 --- a/module-collectd/manifests/plugin/snmp/host.pp +++ b/module-collectd/manifests/plugin/snmp/host.pp @@ -1,10 +1,10 @@ # https://collectd.org/wiki/index.php/Plugin:SNMP define collectd::plugin::snmp::host ( + $collect, $ensure = present, $address = $name, $version = 1, $community = 'public', - $collect, $interval = undef, ) { include collectd diff --git a/module-collectd/templates/plugin/network/server.conf.erb b/module-collectd/templates/plugin/network/server.conf.erb index daab982ba..417bf0674 100644 --- a/module-collectd/templates/plugin/network/server.conf.erb +++ b/module-collectd/templates/plugin/network/server.conf.erb @@ -17,4 +17,7 @@ <% else -%> Server "<%= @name %>" "<%= @port %>" <% end -%> +<% if ! @forward.nil? -%> + Forward <%= @forward %> +<% end -%> diff --git a/module-collectd/templates/plugin/rrdcached.conf.erb b/module-collectd/templates/plugin/rrdcached.conf.erb index b469924d8..92917a88f 100644 --- a/module-collectd/templates/plugin/rrdcached.conf.erb +++ b/module-collectd/templates/plugin/rrdcached.conf.erb @@ -2,10 +2,10 @@ DaemonAddress "<%= @daemonaddress %>" DataDir "<%= @datadir %>" <% unless @createfiles.nil? -%> - CreateFiles "<%= @createfiles %>" + CreateFiles <%= @createfiles %> <% end -%> <% unless @createfilesasync.nil? -%> - CreateFilesAsync "<%= @createfilesasync %>" + CreateFilesAsync <%= @createfilesasync %> <% end -%> <% if @stepsize -%> StepSize "<%= @stepsize %>" diff --git a/module-collectd/tests/plugins/iptables.pp b/module-collectd/tests/plugins/iptables.pp index fac2e3a5c..e1fec41d7 100644 --- a/module-collectd/tests/plugins/iptables.pp +++ b/module-collectd/tests/plugins/iptables.pp @@ -1,7 +1,7 @@ include collectd class { 'collectd::plugin::iptables': - chains => { + chains => { 'nat' => 'In_SSH', 'filter' => 'HTTP' }, diff --git a/module-collectd/tests/plugins/mysql.pp b/module-collectd/tests/plugins/mysql.pp index 6c5f4d6e0..7eafd4f6b 100644 --- a/module-collectd/tests/plugins/mysql.pp +++ b/module-collectd/tests/plugins/mysql.pp @@ -1,8 +1,8 @@ include collectd collectd::plugin::mysql::database { 'puppetdb': - host => 'localhost', - username => 'stahmna', - password => 'yermom', - port => '3306', + host => 'localhost', + username => 'stahmna', + password => 'yermom', + port => '3306', } diff --git a/module-collectd/tests/plugins/perl.pp b/module-collectd/tests/plugins/perl.pp index 55672845b..cf5c1554e 100644 --- a/module-collectd/tests/plugins/perl.pp +++ b/module-collectd/tests/plugins/perl.pp @@ -16,8 +16,8 @@ destination => '/tmp', order => 99, config => { - 'foo' => 'bar', - 'key' => [ 'val1', 'val2' ], + 'foo' => 'bar', + 'key' => [ 'val1', 'val2' ], } } @@ -37,17 +37,17 @@ collectd::plugin::perl::plugin { 'baar': - module => 'Collectd::Plugins::Bar', - provider => 'package', - source => 'perl-Collectd-Plugins-Bar', - config => { - 'foo' => 'bar', - 'more' => { + module => 'Collectd::Plugins::Bar', + provider => 'package', + source => 'perl-Collectd-Plugins-Bar', + config => { + 'foo' => 'bar', + 'more' => { 'complex' => 'structure', 'no' => [ 'a', 'b' ], 'yes' => { - 'last' => 'level', - 'and' => [ 'array' , 'thing' ] + 'last' => 'level', + 'and' => [ 'array' , 'thing' ] }, }, }, diff --git a/module-collectd/tests/purge_config.pp b/module-collectd/tests/purge_config.pp index 4ca79ff7c..858dcc403 100644 --- a/module-collectd/tests/purge_config.pp +++ b/module-collectd/tests/purge_config.pp @@ -1,7 +1,7 @@ class { 'collectd': - purge => true, - recurse => true, - purge_config => true, + purge => true, + recurse => true, + purge_config => true, } diff --git a/mysql/manifests/backup/mysqlbackup.pp b/mysql/manifests/backup/mysqlbackup.pp index a3a722208..9d92b6c0e 100644 --- a/mysql/manifests/backup/mysqlbackup.pp +++ b/mysql/manifests/backup/mysqlbackup.pp @@ -1,27 +1,26 @@ # See README.me for usage. class mysql::backup::mysqlbackup ( - $backupuser, - $backuppassword, - $backupdir, - $backupdirmode = '0700', - $backupdirowner = 'root', - $backupdirgroup = 'root', - $backupcompress = true, - $backuprotate = 30, - $ignore_events = true, + $backupuser = '', + $backuppassword = '', + $backupdir = '', + $backupdirmode = '0700', + $backupdirowner = 'root', + $backupdirgroup = $mysql::params::root_group, + $backupcompress = true, + $backuprotate = 30, + $ignore_events = true, $delete_before_dump = false, - $backupdatabases = [], - $file_per_database = false, - $ensure = 'present', - $time = ['23', '5'], - $postscript = false, - $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', + $backupdatabases = [], + $file_per_database = false, + $ensure = 'present', + $time = ['23', '5'], + $postscript = false, + $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', ) { mysql_user { "${backupuser}@localhost": ensure => $ensure, password_hash => mysql_password($backuppassword), - provider => 'mysql', require => Class['mysql::server::root_password'], } diff --git a/mysql/manifests/backup/mysqldump.pp b/mysql/manifests/backup/mysqldump.pp index 89ec32f1e..51f912c5d 100644 --- a/mysql/manifests/backup/mysqldump.pp +++ b/mysql/manifests/backup/mysqldump.pp @@ -1,27 +1,26 @@ # See README.me for usage. class mysql::backup::mysqldump ( - $backupuser, - $backuppassword, - $backupdir, - $backupdirmode = '0700', - $backupdirowner = 'root', - $backupdirgroup = 'root', - $backupcompress = true, - $backuprotate = 30, - $ignore_events = true, + $backupuser = '', + $backuppassword = '', + $backupdir = '', + $backupdirmode = '0700', + $backupdirowner = 'root', + $backupdirgroup = $mysql::params::root_group, + $backupcompress = true, + $backuprotate = 30, + $ignore_events = true, $delete_before_dump = false, - $backupdatabases = [], - $file_per_database = false, - $ensure = 'present', - $time = ['23', '5'], - $postscript = false, - $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', + $backupdatabases = [], + $file_per_database = false, + $ensure = 'present', + $time = ['23', '5'], + $postscript = false, + $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', ) { mysql_user { "${backupuser}@localhost": ensure => $ensure, password_hash => mysql_password($backuppassword), - provider => 'mysql', require => Class['mysql::server::root_password'], } @@ -47,7 +46,7 @@ path => '/usr/local/sbin/mysqlbackup.sh', mode => '0700', owner => 'root', - group => 'root', + group => $mysql::params::root_group, content => template('mysql/mysqlbackup.sh.erb'), } diff --git a/mysql/manifests/backup/xtrabackup.pp b/mysql/manifests/backup/xtrabackup.pp index 37eb1a7af..fb4ed6203 100644 --- a/mysql/manifests/backup/xtrabackup.pp +++ b/mysql/manifests/backup/xtrabackup.pp @@ -1,28 +1,27 @@ # See README.me for usage. class mysql::backup::xtrabackup ( - $backupuser, - $backuppassword, - $backupdir, - $backupmethod = 'mysqldump', - $backupdirmode = '0700', - $backupdirowner = 'root', - $backupdirgroup = 'root', - $backupcompress = true, - $backuprotate = 30, - $ignore_events = true, + $backupuser = '', + $backuppassword = '', + $backupdir = '', + $backupmethod = 'mysqldump', + $backupdirmode = '0700', + $backupdirowner = 'root', + $backupdirgroup = $mysql::params::root_group, + $backupcompress = true, + $backuprotate = 30, + $ignore_events = true, $delete_before_dump = false, - $backupdatabases = [], - $file_per_database = false, - $ensure = 'present', - $time = ['23', '5'], - $postscript = false, - $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', + $backupdatabases = [], + $file_per_database = false, + $ensure = 'present', + $time = ['23', '5'], + $postscript = false, + $execpath = '/usr/bin:/usr/sbin:/bin:/sbin', ) { mysql_user { "${backupuser}@localhost": ensure => $ensure, password_hash => mysql_password($backuppassword), - provider => 'mysql', require => Class['mysql::server::root_password'], } diff --git a/mysql/manifests/client/install.pp b/mysql/manifests/client/install.pp index 8ffff5b0c..26e5ec276 100644 --- a/mysql/manifests/client/install.pp +++ b/mysql/manifests/client/install.pp @@ -1,3 +1,4 @@ +# See README.md. class mysql::client::install { if $mysql::client::package_manage { diff --git a/mysql/manifests/server/account_security.pp b/mysql/manifests/server/account_security.pp index 07bdf0133..252572e88 100644 --- a/mysql/manifests/server/account_security.pp +++ b/mysql/manifests/server/account_security.pp @@ -1,3 +1,4 @@ +# See README.md. class mysql::server::account_security { mysql_user { [ 'root@127.0.0.1', diff --git a/mysql/manifests/server/monitor.pp b/mysql/manifests/server/monitor.pp index 9e86b92c7..6b1860983 100644 --- a/mysql/manifests/server/monitor.pp +++ b/mysql/manifests/server/monitor.pp @@ -1,8 +1,8 @@ #This is a helper class to add a monitoring user to the database class mysql::server::monitor ( - $mysql_monitor_username, - $mysql_monitor_password, - $mysql_monitor_hostname + $mysql_monitor_username = '', + $mysql_monitor_password = '', + $mysql_monitor_hostname = '' ) { Anchor['mysql::server::end'] -> Class['mysql::server::monitor'] diff --git a/mysql/manifests/server/service.pp b/mysql/manifests/server/service.pp index 30ff300aa..4d33def68 100644 --- a/mysql/manifests/server/service.pp +++ b/mysql/manifests/server/service.pp @@ -18,10 +18,12 @@ $mysqluser = $options['mysqld']['user'] } - file { $options['mysqld']['log-error']: - ensure => present, - owner => $mysqluser, - group => $::mysql::server::mysql_group, + if $options['mysqld']['log-error'] { + file { $options['mysqld']['log-error']: + ensure => present, + owner => $mysqluser, + group => $::mysql::server::mysql_group, + } } service { 'mysqld': diff --git a/mysql/spec/acceptance/mysql_server_spec.rb b/mysql/spec/acceptance/mysql_server_spec.rb index 06646cbbe..f41e04cad 100644 --- a/mysql/spec/acceptance/mysql_server_spec.rb +++ b/mysql/spec/acceptance/mysql_server_spec.rb @@ -51,5 +51,18 @@ class { 'mysql::server': apply_manifest(pp, :catch_changes => true) end end + + describe 'configuration needed for syslog' do + it 'should work with no errors' do + pp = <<-EOS + class { 'mysql::server': + override_options => { 'mysqld' => { 'log-error' => undef }, 'mysqld_safe' => { 'log-error' => false, 'syslog' => true }}, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + end end diff --git a/mysql/templates/mysqlbackup.sh.erb b/mysql/templates/mysqlbackup.sh.erb index e3ab7cc28..21482087f 100755 --- a/mysql/templates/mysqlbackup.sh.erb +++ b/mysql/templates/mysqlbackup.sh.erb @@ -1,4 +1,8 @@ +<%- if @kernel == 'Linux' -%> #!/bin/bash +<%- else -%> +#!/bin/sh +<%- end -%> # # MySQL Backup Script # Dumps mysql databases to a file for another backup tool to pick up. @@ -27,7 +31,9 @@ PATH=<%= @execpath %> +<%- if @kernel == 'Linux' -%> set -o pipefail +<%- end -%> cleanup() { diff --git a/nova/.fixtures.yml b/nova/.fixtures.yml index 782b316a4..af20848b4 100644 --- a/nova/.fixtures.yml +++ b/nova/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: 'cinder': 'git://github.com/stackforge/puppet-cinder.git' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'ref': '1.2.1' 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' 'keystone': 'git://github.com/stackforge/puppet-keystone.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' diff --git a/nova/manifests/compute.pp b/nova/manifests/compute.pp index b67b972d6..53b0f2d86 100644 --- a/nova/manifests/compute.pp +++ b/nova/manifests/compute.pp @@ -42,7 +42,7 @@ # # [*vncproxy_path*] # (optional) The path at the end of the uri for communication with the VNC proxy server -# Defaults to './vnc_auto.html' +# Defaults to '/vnc_auto.html' # # [*vnc_keymap*] # (optional) The keymap to use with VNC (ls -alh /usr/share/qemu/keymaps to list available keymaps) @@ -142,13 +142,7 @@ } if ($vnc_enabled) { - if ($vncproxy_host) { - $vncproxy_base_url = "${vncproxy_protocol}://${vncproxy_host}:${vncproxy_port}${vncproxy_path}" - # config for vnc proxy - nova_config { - 'DEFAULT/novncproxy_base_url': value => $vncproxy_base_url; - } - } + include ::nova::vncproxy::common } nova_config { diff --git a/nova/manifests/compute/rbd.pp b/nova/manifests/compute/rbd.pp index d520c0ecf..c0c89a45e 100644 --- a/nova/manifests/compute/rbd.pp +++ b/nova/manifests/compute/rbd.pp @@ -38,6 +38,13 @@ # Required to use cephx. # Default to false. # +# [*libvirt_rbd_secret_key*] +# (optional) The cephx key to use as key for the libvirt secret, +# it must be base64 encoded; when not provided this key will be +# requested to the ceph cluster, which assumes the node is +# provided of the client.admin keyring as well. +# Default to undef. +# # [*rbd_keyring*] # (optional) The keyring name to use when retrieving the RBD secret # Default to 'client.nova' @@ -46,6 +53,7 @@ class nova::compute::rbd ( $libvirt_rbd_user, $libvirt_rbd_secret_uuid = false, + $libvirt_rbd_secret_key = undef, $libvirt_images_rbd_pool = 'rbd', $libvirt_images_rbd_ceph_conf = '/etc/ceph/ceph.conf', $rbd_keyring = 'client.nova', @@ -75,8 +83,13 @@ require => File['/etc/nova/secret.xml'] } + if $libvirt_rbd_secret_key { + $libvirt_key = $libvirt_rbd_secret_key + } else { + $libvirt_key = "$(ceph auth get-key ${rbd_keyring})" + } exec { 'set-secret-value virsh': - command => "/usr/bin/virsh secret-set-value --secret ${libvirt_rbd_secret_uuid} --base64 $(ceph auth get-key ${rbd_keyring})", + command => "/usr/bin/virsh secret-set-value --secret ${libvirt_rbd_secret_uuid} --base64 ${libvirt_key}", unless => "/usr/bin/virsh secret-get-value ${libvirt_rbd_secret_uuid}", require => Exec['get-or-set virsh secret'] } diff --git a/nova/manifests/init.pp b/nova/manifests/init.pp index 634f06ab2..08e3937d2 100644 --- a/nova/manifests/init.pp +++ b/nova/manifests/init.pp @@ -463,63 +463,63 @@ if $rpc_backend == 'nova.openstack.common.rpc.impl_kombu' or $rpc_backend == 'rabbit' { # I may want to support exporting and collecting these nova_config { - 'DEFAULT/rabbit_password': value => $rabbit_password, secret => true; - 'DEFAULT/rabbit_userid': value => $rabbit_userid; - 'DEFAULT/rabbit_virtual_host': value => $rabbit_virtual_host; - 'DEFAULT/rabbit_use_ssl': value => $rabbit_use_ssl; + 'oslo_messaging_rabbit/rabbit_password': value => $rabbit_password, secret => true; + 'oslo_messaging_rabbit/rabbit_userid': value => $rabbit_userid; + 'oslo_messaging_rabbit/rabbit_virtual_host': value => $rabbit_virtual_host; + 'oslo_messaging_rabbit/rabbit_use_ssl': value => $rabbit_use_ssl; 'DEFAULT/amqp_durable_queues': value => $amqp_durable_queues; } if $rabbit_use_ssl { if $kombu_ssl_ca_certs { - nova_config { 'DEFAULT/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs; } + nova_config { 'oslo_messaging_rabbit/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs; } } else { - nova_config { 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; } + nova_config { 'oslo_messaging_rabbit/kombu_ssl_ca_certs': ensure => absent; } } if $kombu_ssl_certfile or $kombu_ssl_keyfile { nova_config { - 'DEFAULT/kombu_ssl_certfile': value => $kombu_ssl_certfile; - 'DEFAULT/kombu_ssl_keyfile': value => $kombu_ssl_keyfile; + 'oslo_messaging_rabbit/kombu_ssl_certfile': value => $kombu_ssl_certfile; + 'oslo_messaging_rabbit/kombu_ssl_keyfile': value => $kombu_ssl_keyfile; } } else { nova_config { - 'DEFAULT/kombu_ssl_certfile': ensure => absent; - 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_certfile': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_keyfile': ensure => absent; } } if $kombu_ssl_version { - nova_config { 'DEFAULT/kombu_ssl_version': value => $kombu_ssl_version; } + nova_config { 'oslo_messaging_rabbit/kombu_ssl_version': value => $kombu_ssl_version; } } else { - nova_config { 'DEFAULT/kombu_ssl_version': ensure => absent; } + nova_config { 'oslo_messaging_rabbit/kombu_ssl_version': ensure => absent; } } } else { nova_config { - 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; - 'DEFAULT/kombu_ssl_certfile': ensure => absent; - 'DEFAULT/kombu_ssl_keyfile': ensure => absent; - 'DEFAULT/kombu_ssl_version': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_ca_certs': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_certfile': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_keyfile': ensure => absent; + 'oslo_messaging_rabbit/kombu_ssl_version': ensure => absent; } } if $rabbit_hosts { - nova_config { 'DEFAULT/rabbit_hosts': value => join($rabbit_hosts, ',') } + nova_config { 'oslo_messaging_rabbit/rabbit_hosts': value => join($rabbit_hosts, ',') } } else { - nova_config { 'DEFAULT/rabbit_host': value => $rabbit_host } - nova_config { 'DEFAULT/rabbit_port': value => $rabbit_port } - nova_config { 'DEFAULT/rabbit_hosts': value => "${rabbit_host}:${rabbit_port}" } + nova_config { 'oslo_messaging_rabbit/rabbit_host': value => $rabbit_host } + nova_config { 'oslo_messaging_rabbit/rabbit_port': value => $rabbit_port } + nova_config { 'oslo_messaging_rabbit/rabbit_hosts': value => "${rabbit_host}:${rabbit_port}" } } if $rabbit_ha_queues == undef { if $rabbit_hosts { - nova_config { 'DEFAULT/rabbit_ha_queues': value => true } + nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => true } } else { - nova_config { 'DEFAULT/rabbit_ha_queues': value => false } + nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => false } } } else { - nova_config { 'DEFAULT/rabbit_ha_queues': value => $rabbit_ha_queues } + nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => $rabbit_ha_queues } } } diff --git a/nova/manifests/params.pp b/nova/manifests/params.pp index b24ec182d..50f9b014f 100644 --- a/nova/manifests/params.pp +++ b/nova/manifests/params.pp @@ -47,7 +47,7 @@ 'Fedora': { $special_service_provider = undef } - 'RedHat', 'CentOS', 'Scientific': { + 'RedHat', 'CentOS', 'Scientific', 'OracleLinux': { if (versioncmp($::operatingsystemmajrelease, '7') < 0) { $special_service_provider = 'init' } else { diff --git a/nova/manifests/vncproxy.pp b/nova/manifests/vncproxy.pp index eb33a3dc0..63ba31faa 100644 --- a/nova/manifests/vncproxy.pp +++ b/nova/manifests/vncproxy.pp @@ -24,18 +24,27 @@ # (optional) The state of the nova-novncproxy package # Defaults to 'present' # +# [*vncproxy_protocol*] +# (optional) The protocol to communicate with the VNC proxy server +# Defaults to 'http' +# +# [*vncproxy_path*] +# (optional) The path at the end of the uri for communication with the VNC +# proxy server +# Defaults to '/vnc_auto.html' +# class nova::vncproxy( - $enabled = false, - $manage_service = true, - $host = '0.0.0.0', - $port = '6080', - $ensure_package = 'present' + $enabled = false, + $manage_service = true, + $vncproxy_protocol = 'http', + $host = '0.0.0.0', + $port = '6080', + $vncproxy_path = '/vnc_auto.html', + $ensure_package = 'present' ) { include ::nova::params - # TODO make this work on Fedora - # See http://nova.openstack.org/runnova/vncconsole.html for more details. nova_config { @@ -43,6 +52,8 @@ 'DEFAULT/novncproxy_port': value => $port; } + include ::nova::vncproxy::common + if ! defined(Package['python-numpy']) { package { 'python-numpy': ensure => present, diff --git a/nova/manifests/vncproxy/common.pp b/nova/manifests/vncproxy/common.pp new file mode 100644 index 000000000..15b46330d --- /dev/null +++ b/nova/manifests/vncproxy/common.pp @@ -0,0 +1,54 @@ +# == Class: nova::vncproxy::common +# +# [*vncproxy_host*] +# (optional) The host of the VNC proxy server +# Defaults to false +# +# [*vncproxy_protocol*] +# (optional) The protocol to communicate with the VNC proxy server +# Defaults to 'http' +# +# [*vncproxy_port*] +# (optional) The port to communicate with the VNC proxy server +# Defaults to '6080' +# +# [*vncproxy_path*] +# (optional) The path at the end of the uri for communication with the VNC proxy server +# Defaults to '/vnc_auto.html' +# +class nova::vncproxy::common ( + $vncproxy_host = undef, + $vncproxy_protocol = undef, + $vncproxy_port = undef, + $vncproxy_path = undef, +) { + + $vncproxy_host_real = pick( + $vncproxy_host, + $::nova::compute::vncproxy_host, + $::nova::vncproxy::host, + false) + $vncproxy_protocol_real = pick( + $vncproxy_protocol, + $::nova::compute::vncproxy_protocol, + $::nova::vncproxy::vncproxy_protocol, + 'http') + $vncproxy_port_real = pick( + $vncproxy_port, + $::nova::compute::vncproxy_port, + $::nova::vncproxy::port, + 6080) + $vncproxy_path_real = pick( + $vncproxy_path, + $::nova::compute::vncproxy_path, + $::nova::vncproxy::vncproxy_path, + '/vnc_auto.html') + + if ($vncproxy_host_real) { + $vncproxy_base_url = "${vncproxy_protocol_real}://${vncproxy_host_real}:${vncproxy_port_real}${vncproxy_path_real}" + # config for vnc proxy + nova_config { + 'DEFAULT/novncproxy_base_url': value => $vncproxy_base_url; + } + } +} diff --git a/nova/spec/classes/nova_compute_rbd_spec.rb b/nova/spec/classes/nova_compute_rbd_spec.rb index f442810f8..87c529f23 100644 --- a/nova/spec/classes/nova_compute_rbd_spec.rb +++ b/nova/spec/classes/nova_compute_rbd_spec.rb @@ -90,6 +90,21 @@ end end + context 'when using cephx and passing libvirt_rbd_secret_key' do + before :each do + params.merge!( + :libvirt_rbd_secret_uuid => 'UUID', + :libvirt_rbd_secret_key => 'LIBVIRT/SECRET/KEY', + ) + end + + it 'set libvirt secret key from passed key' do + is_expected.to contain_exec('set-secret-value virsh').with( + :command => "/usr/bin/virsh secret-set-value --secret #{params[:libvirt_rbd_secret_uuid]} --base64 #{params[:libvirt_rbd_secret_key]}" + ) + end + end + end context 'on Debian platforms' do diff --git a/nova/spec/classes/nova_init_spec.rb b/nova/spec/classes/nova_init_spec.rb index aacf4a4e6..fc319b1b1 100644 --- a/nova/spec/classes/nova_init_spec.rb +++ b/nova/spec/classes/nova_init_spec.rb @@ -57,11 +57,11 @@ it 'configures rabbit' do is_expected.to contain_nova_config('DEFAULT/rpc_backend').with_value('rabbit') - is_expected.to contain_nova_config('DEFAULT/rabbit_host').with_value('localhost') - is_expected.to contain_nova_config('DEFAULT/rabbit_password').with_value('guest').with_secret(true) - is_expected.to contain_nova_config('DEFAULT/rabbit_port').with_value('5672') - is_expected.to contain_nova_config('DEFAULT/rabbit_userid').with_value('guest') - is_expected.to contain_nova_config('DEFAULT/rabbit_virtual_host').with_value('/') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_host').with_value('localhost') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_password').with_value('guest').with_secret(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_port').with_value('5672') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_userid').with_value('guest') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_virtual_host').with_value('/') end it 'configures various things' do @@ -128,11 +128,11 @@ it 'configures rabbit' do is_expected.to contain_nova_config('DEFAULT/rpc_backend').with_value('rabbit') - is_expected.to contain_nova_config('DEFAULT/rabbit_host').with_value('rabbit') - is_expected.to contain_nova_config('DEFAULT/rabbit_password').with_value('password').with_secret(true) - is_expected.to contain_nova_config('DEFAULT/rabbit_port').with_value('5673') - is_expected.to contain_nova_config('DEFAULT/rabbit_userid').with_value('rabbit_user') - is_expected.to contain_nova_config('DEFAULT/rabbit_virtual_host').with_value('/') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_host').with_value('rabbit') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_password').with_value('password').with_secret(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_port').with_value('5673') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_userid').with_value('rabbit_user') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_virtual_host').with_value('/') end it 'configures memcached_servers' do @@ -221,16 +221,16 @@ end it 'configures rabbit' do - is_expected.to_not contain_nova_config('DEFAULT/rabbit_host') - is_expected.to_not contain_nova_config('DEFAULT/rabbit_port') - is_expected.to contain_nova_config('DEFAULT/rabbit_hosts').with_value('rabbit:5673,rabbit2:5674') - is_expected.to contain_nova_config('DEFAULT/rabbit_ha_queues').with_value(true) - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value(false) + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_host') + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_port') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_hosts').with_value('rabbit:5673,rabbit2:5674') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_ha_queues').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value(false) is_expected.to contain_nova_config('DEFAULT/amqp_durable_queues').with_value(false) - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_ca_certs').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_certfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_keyfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_version').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_ca_certs').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_certfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_keyfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_version').with_ensure('absent') end end @@ -240,11 +240,11 @@ end it 'configures rabbit' do - is_expected.to_not contain_nova_config('DEFAULT/rabbit_host') - is_expected.to_not contain_nova_config('DEFAULT/rabbit_port') - is_expected.to contain_nova_config('DEFAULT/rabbit_hosts').with_value('rabbit:5673') - is_expected.to contain_nova_config('DEFAULT/rabbit_ha_queues').with_value(true) - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value(false) + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_host') + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_port') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_hosts').with_value('rabbit:5673') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_ha_queues').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value(false) is_expected.to contain_nova_config('DEFAULT/amqp_durable_queues').with_value(false) end end @@ -255,7 +255,7 @@ end it 'configures rabbit' do - is_expected.to contain_nova_config('DEFAULT/rabbit_ha_queues').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_ha_queues').with_value(true) end end @@ -266,16 +266,16 @@ end it 'configures rabbit' do - is_expected.to_not contain_nova_config('DEFAULT/rabbit_host') - is_expected.to_not contain_nova_config('DEFAULT/rabbit_port') - is_expected.to contain_nova_config('DEFAULT/rabbit_hosts').with_value('rabbit:5673') - is_expected.to contain_nova_config('DEFAULT/rabbit_ha_queues').with_value(true) - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value(false) + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_host') + is_expected.to_not contain_nova_config('oslo_messaging_rabbit/rabbit_port') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_hosts').with_value('rabbit:5673') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_ha_queues').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value(false) is_expected.to contain_nova_config('DEFAULT/amqp_durable_queues').with_value(true) - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_ca_certs').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_certfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_keyfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_version').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_ca_certs').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_certfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_keyfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_version').with_ensure('absent') end end @@ -290,11 +290,11 @@ end it 'configures rabbit' do - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value(true) - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_ca_certs').with_value('/etc/ca.cert') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_certfile').with_value('/etc/certfile') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_keyfile').with_value('/etc/key') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_version').with_value('TLSv1') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_ca_certs').with_value('/etc/ca.cert') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_certfile').with_value('/etc/certfile') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_keyfile').with_value('/etc/key') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_version').with_value('TLSv1') end end @@ -305,11 +305,11 @@ end it 'configures rabbit' do - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value(true) - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_ca_certs').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_certfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_keyfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_version').with_value('TLSv1') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value(true) + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_ca_certs').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_certfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_keyfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_version').with_value('TLSv1') end end @@ -323,11 +323,11 @@ end it 'configures rabbit' do - is_expected.to contain_nova_config('DEFAULT/rabbit_use_ssl').with_value('false') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_ca_certs').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_certfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_keyfile').with_ensure('absent') - is_expected.to contain_nova_config('DEFAULT/kombu_ssl_version').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/rabbit_use_ssl').with_value('false') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_ca_certs').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_certfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_keyfile').with_ensure('absent') + is_expected.to contain_nova_config('oslo_messaging_rabbit/kombu_ssl_version').with_ensure('absent') end end diff --git a/nova/spec/classes/nova_vnc_proxy_spec.rb b/nova/spec/classes/nova_vnc_proxy_spec.rb index c24f347ad..4fe3ab612 100644 --- a/nova/spec/classes/nova_vnc_proxy_spec.rb +++ b/nova/spec/classes/nova_vnc_proxy_spec.rb @@ -22,6 +22,7 @@ it { is_expected.to contain_nova_config('DEFAULT/novncproxy_host').with(:value => '0.0.0.0') } it { is_expected.to contain_nova_config('DEFAULT/novncproxy_port').with(:value => '6080') } + it { is_expected.to contain_nova_config('DEFAULT/novncproxy_base_url').with(:value => 'http://0.0.0.0:6080/vnc_auto.html') } it { is_expected.to contain_package('nova-vncproxy').with( :name => 'nova-novncproxy', diff --git a/nova/spec/spec_helper.rb b/nova/spec/spec_helper.rb index 53d4dd02d..172614e99 100644 --- a/nova/spec/spec_helper.rb +++ b/nova/spec/spec_helper.rb @@ -5,3 +5,5 @@ c.alias_it_should_behave_like_to :it_configures, 'configures' c.alias_it_should_behave_like_to :it_raises, 'raises' end + +at_exit { RSpec::Puppet::Coverage.report! } diff --git a/ntp/.gitignore b/ntp/.gitignore index b5db85e05..874db461f 100644 --- a/ntp/.gitignore +++ b/ntp/.gitignore @@ -7,3 +7,4 @@ spec/fixtures/ coverage/ .idea/ *.iml +log/ diff --git a/ntp/README.markdown b/ntp/README.markdown index f7209ef9c..353923f16 100644 --- a/ntp/README.markdown +++ b/ntp/README.markdown @@ -191,10 +191,22 @@ Provides a request key to be used by NTP. Valid options: string. Default value: #### `keys_trusted`: Provides one or more keys to be trusted by NTP. Valid options: array of keys. Default value: [ ] +#### `leapfile` + +Specifies a leap second file for NTP to use. Valid options: string containing an absolute path. Default value: ' ' + #### `logfile` Specifies a log file for NTP to use instead of syslog. Valid options: string containing an absolute path. Default value: ' ' +####`minpoll` + +Tells Puppet to use non-standard minimal poll interval of upstream servers. Valid options: 3 to 16. Default option: undef. + +####`maxpoll` + +Tells Puppet to use non-standard maximal poll interval of upstream servers. Valid options: 3 to 16. Default option: undef, except FreeBSD (on FreeBSD `maxpoll` set 9 by default). + ####`package_ensure` Tells Puppet whether the NTP package should be installed, and what version. Valid options: 'present', 'latest', or a specific version number. Default value: 'present' @@ -209,7 +221,11 @@ Tells Puppet what NTP package to manage. Valid options: string. Default value: ' ####`panic` -Specifies whether NTP should "panic" in the event of a very large clock skew. Valid options: 'true' or 'false'. Default value: 'true' (except on virtual machines, where major time shifts are normal) +Specifies whether NTP should "panic" in the event of a very large clock skew. Applies only if `tinker` option set to "true" or in case your environment is in virtual machine. Valid options: unsigned shortint digit. Default value: 0 if environment is virtual, undef in all other cases. + +####`peers` + +List of ntp servers which the local clock can be synchronised against, or which can synchronise against the local clock. ####`preferred_servers` @@ -257,10 +273,22 @@ Tells Puppet whether to manage the NTP service. Valid options: 'true' or 'false' Tells Puppet what NTP service to manage. Valid options: string. Default value: varies by operating system +####`stepout` + +Tells puppet to change stepout. Applies only if `tinker` value is 'true'. Valid options: unsigned shortint digit. Default value: undef. + +####`tinker` + +Tells Puppet to enable tinker options. Valid options: 'true' of 'false'. Default value: 'false' + ####`udlc` Specifies whether to configure ntp to use the undisciplined local clock as a time source. Valid options: 'true' or 'false'. Default value: 'false' +####`udlc_stratum` + +Specifies the stratum the server should operate at when using the undisciplined local clock as the time source. It is strongly suggested that this value be set to no less than 10 where ntpd may be accessible outside your immediate, controlled network. Default value: 10 + ##Limitations This module has been tested on [all PE-supported platforms](https://forge.puppetlabs.com/supported#compat-matrix), and no issues have been identified. diff --git a/ntp/manifests/init.pp b/ntp/manifests/init.pp index 14adf5952..1eea5a036 100644 --- a/ntp/manifests/init.pp +++ b/ntp/manifests/init.pp @@ -7,6 +7,7 @@ $disable_monitor = $ntp::params::disable_monitor, $fudge = $ntp::params::fudge, $driftfile = $ntp::params::driftfile, + $leapfile = $ntp::params::leapfile, $logfile = $ntp::params::logfile, $iburst_enable = $ntp::params::iburst_enable, $keys_enable = $ntp::params::keys_enable, @@ -14,10 +15,13 @@ $keys_controlkey = $ntp::params::keys_controlkey, $keys_requestkey = $ntp::params::keys_requestkey, $keys_trusted = $ntp::params::keys_trusted, + $minpoll = $ntp::params::minpoll, + $maxpoll = $ntp::params::maxpoll, $package_ensure = $ntp::params::package_ensure, $package_manage = $ntp::params::package_manage, $package_name = $ntp::params::package_name, $panic = $ntp::params::panic, + $peers = $ntp::params::peers, $preferred_servers = $ntp::params::preferred_servers, $restrict = $ntp::params::restrict, $interfaces = $ntp::params::interfaces, @@ -26,7 +30,10 @@ $service_ensure = $ntp::params::service_ensure, $service_manage = $ntp::params::service_manage, $service_name = $ntp::params::service_name, - $udlc = $ntp::params::udlc + $stepout = $ntp::params::stepout, + $tinker = $ntp::params::tinker, + $udlc = $ntp::params::udlc, + $udlc_stratum = $ntp::params::udlc_stratum, ) inherits ntp::params { validate_bool($broadcastclient) @@ -36,15 +43,18 @@ validate_bool($disable_monitor) validate_absolute_path($driftfile) if $logfile { validate_absolute_path($logfile) } + if $leapfile { validate_absolute_path($leapfile) } validate_bool($iburst_enable) validate_bool($keys_enable) validate_re($keys_controlkey, ['^\d+$', '']) validate_re($keys_requestkey, ['^\d+$', '']) validate_array($keys_trusted) + if $minpoll { validate_numeric($minpoll, 16, 3) } + if $maxpoll { validate_numeric($maxpoll, 16, 3) } validate_string($package_ensure) validate_bool($package_manage) validate_array($package_name) - validate_bool($panic) + if $panic { validate_numeric($panic, 65535, 0) } validate_array($preferred_servers) validate_array($restrict) validate_array($interfaces) @@ -54,7 +64,10 @@ validate_string($service_ensure) validate_bool($service_manage) validate_string($service_name) + if $stepout { validate_numeric($stepout, 65535, 0) } + validate_bool($tinker) validate_bool($udlc) + validate_array($peers) if $autoupdate { notice('autoupdate parameter has been deprecated and replaced with package_ensure. Set this to latest for the same behavior as autoupdate => true.') diff --git a/ntp/manifests/params.pp b/ntp/manifests/params.pp index 47a898001..cf9c01180 100644 --- a/ntp/manifests/params.pp +++ b/ntp/manifests/params.pp @@ -8,12 +8,17 @@ $keys_requestkey = '' $keys_trusted = [] $logfile = undef + $minpoll = undef + $leapfile = undef $package_ensure = 'present' + $peers = [] $preferred_servers = [] $service_enable = true $service_ensure = 'running' $service_manage = true + $stepout = undef $udlc = false + $udlc_stratum = '10' $interfaces = [] $disable_auth = false $broadcastclient = false @@ -21,14 +26,6 @@ # Allow a list of fudge options $fudge = [] - # On virtual machines allow large clock skews. - # TODO Change this to str2bool($::is_virtual) when stdlib dependency is >= 4.0.0 - # NOTE The "x${var}" is just to avoid lint quoted variable warning. - $panic = "x${::is_virtual}" ? { - 'xtrue' => false, - default => true, - } - $default_config = '/etc/ntp.conf' $default_keys_file = '/etc/ntp/keys' $default_driftfile = '/var/lib/ntp/drift' @@ -40,6 +37,15 @@ default => true, } + if str2bool($::is_virtual) { + $tinker = true + $panic = 0 + } + else { + $tinker = false + $panic = undef + } + case $::osfamily { 'AIX': { $config = $default_config @@ -58,6 +64,7 @@ '2.debian.pool.ntp.org', '3.debian.pool.ntp.org', ] + $maxpoll = undef } 'Debian': { $config = $default_config @@ -78,6 +85,7 @@ '2.debian.pool.ntp.org', '3.debian.pool.ntp.org', ] + $maxpoll = undef } 'RedHat': { $config = $default_config @@ -97,6 +105,7 @@ '1.centos.pool.ntp.org', '2.centos.pool.ntp.org', ] + $maxpoll = undef } 'Suse': { if $::operatingsystem == 'SLES' and $::operatingsystemmajrelease == '12' @@ -123,6 +132,7 @@ '2.opensuse.pool.ntp.org', '3.opensuse.pool.ntp.org', ] + $maxpoll = undef } 'FreeBSD': { $config = $default_config @@ -138,11 +148,12 @@ $service_name = $default_service_name $iburst_enable = true $servers = [ - '0.freebsd.pool.ntp.org maxpoll 9', - '1.freebsd.pool.ntp.org maxpoll 9', - '2.freebsd.pool.ntp.org maxpoll 9', - '3.freebsd.pool.ntp.org maxpoll 9', + '0.freebsd.pool.ntp.org', + '1.freebsd.pool.ntp.org', + '2.freebsd.pool.ntp.org', + '3.freebsd.pool.ntp.org', ] + $maxpoll = 9 } 'Archlinux': { $config = $default_config @@ -162,6 +173,7 @@ '1.pool.ntp.org', '2.pool.ntp.org', ] + $maxpoll = undef } 'Solaris': { $config = '/etc/inet/ntp.conf' @@ -185,6 +197,7 @@ '2.pool.ntp.org', '3.pool.ntp.org', ] + $maxpoll = undef } # Gentoo was added as its own $::osfamily in Facter 1.7.0 'Gentoo': { @@ -206,6 +219,7 @@ '2.gentoo.pool.ntp.org', '3.gentoo.pool.ntp.org', ] + $maxpoll = undef } 'Linux': { # Account for distributions that don't have $::osfamily specific settings. @@ -230,6 +244,7 @@ '2.gentoo.pool.ntp.org', '3.gentoo.pool.ntp.org', ] + $maxpoll = undef } default: { fail("The ${module_name} module is not supported on an ${::operatingsystem} distribution.") diff --git a/ntp/metadata.json b/ntp/metadata.json index 962d11e4a..96366b7bb 100644 --- a/ntp/metadata.json +++ b/ntp/metadata.json @@ -90,6 +90,6 @@ ], "description": "NTP Module for Debian, Ubuntu, CentOS, RHEL, OEL, Fedora, FreeBSD, ArchLinux and Gentoo.", "dependencies": [ - {"name":"puppetlabs/stdlib","version_requirement":">= 4.5.0 < 5.0.0"} + {"name":"puppetlabs/stdlib","version_requirement":">= 4.6.0 < 5.0.0"} ] } diff --git a/ntp/spec/acceptance/ntp_parameters_spec.rb b/ntp/spec/acceptance/ntp_parameters_spec.rb index e4c230d7e..2ac554d9c 100644 --- a/ntp/spec/acceptance/ntp_parameters_spec.rb +++ b/ntp/spec/acceptance/ntp_parameters_spec.rb @@ -139,33 +139,33 @@ class { 'ntp': end end - describe 'panic => false' do - it 'enables the tinker panic setting' do + describe 'panic => 0' do + it 'disables the tinker panic setting' do pp = <<-EOS class { 'ntp': - panic => false, + panic => 0, } EOS apply_manifest(pp, :catch_failures => true) end describe file("#{config}") do - its(:content) { should match 'tinker panic' } + its(:content) { should match 'tinker panic 0' } end end - describe 'panic => true' do - it 'disables the tinker panic setting' do + describe 'panic => 1' do + it 'enables the tinker panic setting' do pp = <<-EOS class { 'ntp': - panic => true, + panic => 1, } EOS apply_manifest(pp, :catch_failures => true) end describe file("#{config}") do - its(:content) { should_not match 'tinker panic 0' } + its(:content) { should match 'tinker panic 1' } end end @@ -181,4 +181,16 @@ class { 'ntp': end end + describe 'udlc_stratum' do + it 'sets the stratum value when using udlc' do + pp = "class { 'ntp': udlc => true, udlc_stratum => 10 }" + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{config}") do + it { should be_file } + its(:content) { should match 'stratum 10' } + end + end + end diff --git a/ntp/spec/classes/ntp_spec.rb b/ntp/spec/classes/ntp_spec.rb index 522afbd00..81489db6e 100644 --- a/ntp/spec/classes/ntp_spec.rb +++ b/ntp/spec/classes/ntp_spec.rb @@ -87,11 +87,12 @@ context "when set" do let(:params) {{ :servers => ['a', 'b', 'c', 'd'], - :preferred_servers => ['a', 'b'] + :preferred_servers => ['a', 'b'], + :iburst_enable => false, }} it { should contain_file('/etc/ntp.conf').with({ - 'content' => /server a( iburst)? prefer\nserver b( iburst)? prefer\nserver c( iburst)?\nserver d( iburst)?/}) + 'content' => /server a prefer( maxpoll 9)?\nserver b prefer( maxpoll 9)?\nserver c( maxpoll 9)?\nserver d( maxpoll 9)?/}) } end context "when not set" do @@ -247,7 +248,7 @@ it do should contain_file('/etc/ntp.conf').with({ - 'content' => /iburst\n/, + 'content' => /iburst/, }) end end @@ -265,6 +266,181 @@ end end + describe 'with tinker parameter changed' do + describe 'when set to false' do + context 'when panic or stepout not overriden' do + let(:params) {{ + :tinker => false, + }} + + it do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker /, + }) + end + end + + context 'when panic overriden' do + let(:params) {{ + :tinker => false, + :panic => 257, + }} + + it do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker /, + }) + end + end + + context 'when stepout overriden' do + let(:params) {{ + :tinker => false, + :stepout => 5, + }} + + it do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker /, + }) + end + end + + context 'when panic and stepout overriden' do + let(:params) {{ + :tinker => false, + :panic => 257, + :stepout => 5, + }} + + it do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker /, + }) + end + end + end + describe 'when set to true' do + context 'when only tinker set to true' do + let(:params) {{ + :tinker => true, + }} + + it do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker /, + }) + end + end + + context 'when panic changed' do + let(:params) {{ + :tinker => true, + :panic => 257, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker panic 257\n/, + }) + end + end + + context 'when stepout changed' do + let(:params) {{ + :tinker => true, + :stepout => 5, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker stepout 5\n/, + }) + end + end + + context 'when panic and stepout changed' do + let(:params) {{ + :tinker => true, + :panic => 257, + :stepout => 5, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /^tinker panic 257 stepout 5\n/, + }) + end + end + end + end + + describe 'with parameters minpoll or maxpoll changed from default' do + context 'when minpoll changed from default' do + let(:params) {{ + :minpoll => 3, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /minpoll 3/, + }) + end + end + + context 'when maxpoll changed from default' do + let(:params) {{ + :maxpoll => 12, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /maxpoll 12\n/, + }) + end + end + + context 'when minpoll and maxpoll changed from default simultaneously' do + let(:params) {{ + :minpoll => 3, + :maxpoll => 12, + }} + + it do + should contain_file('/etc/ntp.conf').with({ + 'content' => /minpoll 3 maxpoll 12\n/, + }) + end + end + end + + describe 'with parameter leapfile' do + context 'when set to true' do + let(:params) {{ + :servers => ['a', 'b', 'c', 'd'], + :leapfile => '/etc/leap-seconds.3629404800', + }} + + it 'should contain leapfile setting' do + should contain_file('/etc/ntp.conf').with({ + 'content' => /^leapfile \/etc\/leap-seconds\.3629404800\n/, + }) + end + end + + context 'when set to false' do + let(:params) {{ + :servers => ['a', 'b', 'c', 'd'], + }} + + it 'should not contain a leapfile line' do + should_not contain_file('/etc/ntp.conf').with({ + 'content' => /leapfile /, + }) + end + end + end + describe 'with parameter logfile' do context 'when set to true' do let(:params) {{ @@ -291,6 +467,33 @@ end end end + + describe 'peers' do + context 'when empty' do + let(:params) do + { + :peers => [] + } + end + + it 'should not contain a peer line' do + should contain_file('/etc/ntp.conf').without_content(/^peer/) + end + end + + context 'set' do + let(:params) do + { + :peers => ['foo', 'bar'], + } + end + + it 'should contain the peer lines' do + should contain_file('/etc/ntp.conf').with_content(/peer foo/) + should contain_file('/etc/ntp.conf').with_content(/peer bar/) + end + end + end end end @@ -363,7 +566,7 @@ it 'uses the freebsd ntp servers by default' do should contain_file('/etc/ntp.conf').with({ - 'content' => /server \d.freebsd.pool.ntp.org maxpoll 9 iburst/, + 'content' => /server \d.freebsd.pool.ntp.org iburst maxpoll 9/, }) end end diff --git a/ntp/spec/spec_helper_acceptance.rb b/ntp/spec/spec_helper_acceptance.rb index 1a4bea19a..6b6f1b8fa 100644 --- a/ntp/spec/spec_helper_acceptance.rb +++ b/ntp/spec/spec_helper_acceptance.rb @@ -20,7 +20,7 @@ on host, "mkdir -p #{host['distmoduledir']}" if host['platform'] =~ /sles-12/i || host['platform'] =~ /solaris-11/i apply_manifest_on(host, 'package{"git":}') - on host, 'git clone -b 4.3.x https://github.com/puppetlabs/puppetlabs-stdlib /etc/puppetlabs/puppet/modules/stdlib' + on host, 'git clone -b 4.6.x https://github.com/puppetlabs/puppetlabs-stdlib /etc/puppetlabs/puppet/modules/stdlib' else on host, puppet('module install puppetlabs-stdlib'), {:acceptable_exit_codes => [0, 1]} end diff --git a/ntp/templates/ntp.conf.erb b/ntp/templates/ntp.conf.erb index 2393087f1..c913569b8 100644 --- a/ntp/templates/ntp.conf.erb +++ b/ntp/templates/ntp.conf.erb @@ -1,9 +1,11 @@ # ntp.conf: Managed by puppet. # -<% if @panic == false -%> -# Keep ntpd from panicking in the event of a large clock skew -# when a VM guest is suspended and resumed. -tinker panic 0 +<% if @tinker == true and (@panic or @stepout) -%> +# Enable next tinker options: +# panic - keep ntpd from panicking in the event of a large clock skew +# when a VM guest is suspended and resumed; +# stepout - allow ntpd change offset faster +tinker<% if @panic -%> panic <%= @panic %><% end %><% if @stepout -%> stepout <%= @stepout %><% end %> <% end -%> <% if @disable_monitor == true -%> @@ -34,15 +36,21 @@ interface listen <%= interface %> broadcastclient <% end -%> +# Set up servers for ntpd with next options: +# server - IP address or DNS name of upstream NTP server +# iburst - allow send sync packages faster if upstream unavailable +# prefer - select preferrable server +# minpoll - set minimal update frequency +# maxpoll - set maximal update frequency <% [@servers].flatten.each do |server| -%> -server <%= server %><% if @iburst_enable == true -%> iburst<% end %><% if @preferred_servers.include?(server) -%> prefer<% end %> +server <%= server %><% if @iburst_enable == true -%> iburst<% end %><% if @preferred_servers.include?(server) -%> prefer<% end %><% if @minpoll -%> minpoll <%= @minpoll %><% end %><% if @maxpoll -%> maxpoll <%= @maxpoll %><% end %> <% end -%> <% if @udlc -%> # Undisciplined Local Clock. This is a fake driver intended for backup # and when no outside source of synchronized time is available. server 127.127.1.0 -fudge 127.127.1.0 stratum 10 +fudge 127.127.1.0 stratum <%= @udlc_stratum %> restrict 127.127.1.0 <% end -%> @@ -54,6 +62,13 @@ driftfile <%= @driftfile %> logfile <%= @logfile %> <% end -%> +<% unless @peers.empty? -%> +# Peers +<% [@peers].flatten.each do |peer| -%> +peer <%= peer %> +<% end -%> +<% end -%> + <% if @keys_enable -%> keys <%= @keys_file %> <% unless @keys_trusted.empty? -%> @@ -70,3 +85,8 @@ controlkey <%= @keys_controlkey %> <% [@fudge].flatten.each do |entry| -%> fudge <%= entry %> <% end -%> + +<% unless @leapfile.nil? -%> +# Leapfile +leapfile <%= @leapfile %> +<% end -%> diff --git a/openstack_extras/LICENSE b/openstack_extras/LICENSE index 96f12d349..88a11a0e7 100644 --- a/openstack_extras/LICENSE +++ b/openstack_extras/LICENSE @@ -1,201 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2012 OpenStack Foundation - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +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 - 1. Definitions. + http://www.apache.org/licenses/LICENSE-2.0 - "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 2014 OpenStack Foundation - - 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. +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/openstacklib/.fixtures.yml b/openstacklib/.fixtures.yml index a07981ce7..bcf98bc41 100644 --- a/openstacklib/.fixtures.yml +++ b/openstacklib/.fixtures.yml @@ -1,12 +1,12 @@ fixtures: repositories: apache: git://github.com/puppetlabs/puppetlabs-apache.git - concat: git://github.com/puppetlabs/puppetlabs-concat.git + concat: + repo: 'git://github.com/puppetlabs/puppetlabs-concat.git' + ref: '1.2.1' mysql: git://github.com/puppetlabs/puppetlabs-mysql.git postgresql: git://github.com/puppetlabs/puppetlabs-postgresql.git stdlib: git://github.com/puppetlabs/puppetlabs-stdlib.git - rabbitmq: - repo: 'git://github.com/puppetlabs/puppetlabs-rabbitmq' - ref: 'origin/4.x' + rabbitmq: 'git://github.com/puppetlabs/puppetlabs-rabbitmq' symlinks: 'openstacklib': "#{source_dir}" diff --git a/openstacklib/LICENSE b/openstacklib/LICENSE index 7aaad113c..88a11a0e7 100644 --- a/openstacklib/LICENSE +++ b/openstacklib/LICENSE @@ -1,201 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2012 OpenStack Foundation - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +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 - 1. Definitions. + http://www.apache.org/licenses/LICENSE-2.0 - "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 2014 Puppet Labs Inc - - 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. +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/openstacklib/lib/puppet/provider/openstack.rb b/openstacklib/lib/puppet/provider/openstack.rb index ec1cffe2b..391e327f0 100644 --- a/openstacklib/lib/puppet/provider/openstack.rb +++ b/openstacklib/lib/puppet/provider/openstack.rb @@ -106,46 +106,51 @@ def authenticate_request(service, action, *args) private def password_credentials_set?(auth_params) - auth_params && auth_params['username'] && auth_params['password'] && auth_params['tenant_name'] && auth_params['auth_url'] + auth_params && auth_params['username'] && auth_params['password'] && auth_params['project_name'] && auth_params['auth_url'] end - def openrc_set?(auth_params) auth_params && auth_params['openrc'] end - def service_credentials_set?(auth_params) - auth_params && auth_params['token'] && auth_params['auth_url'] + auth_params && auth_params['token'] && auth_params['url'] end - def self.env_vars_set? - ENV['OS_USERNAME'] && ENV['OS_PASSWORD'] && ENV['OS_TENANT_NAME'] && ENV['OS_AUTH_URL'] + ENV['OS_USERNAME'] && ENV['OS_PASSWORD'] && ENV['OS_PROJECT_NAME'] && ENV['OS_AUTH_URL'] end - def env_vars_set? self.class.env_vars_set? end + def self.password_auth_args(credentials) + creds = [ '--os-username', credentials['username'], + '--os-password', credentials['password'], + '--os-project-name', credentials['project_name'], + '--os-auth-url', credentials['auth_url'] ] + + if credentials.include?('project_domain_name') + creds << '--os-project-domain-name' + creds << credentials['project_domain_name'] + end + if credentials.include?('user_domain_name') + creds << '--os-user-domain-name' + creds << credentials['user_domain_name'] + end - def self.password_auth_args(credentials) - ['--os-username', credentials['username'], - '--os-password', credentials['password'], - '--os-tenant-name', credentials['tenant_name'], - '--os-auth-url', credentials['auth_url']] + creds end def password_auth_args(credentials) self.class.password_auth_args(credentials) end - def self.token_auth_args(credentials) - ['--os-token', credentials['token'], - '--os-url', credentials['auth_url']] + [ '--os-token', credentials['token'], + '--os-url', credentials['url'] ] end def token_auth_args(credentials) @@ -163,7 +168,6 @@ def get_credentials_from_openrc(file) return creds end - def self.get_credentials_from_env env = ENV.to_hash.dup.delete_if { |key, _| ! (key =~ /^OS_/) } credentials = {} diff --git a/openstacklib/lib/puppet/util/openstack.rb b/openstacklib/lib/puppet/util/openstack.rb index 867964afb..916aa8e16 100644 --- a/openstacklib/lib/puppet/util/openstack.rb +++ b/openstacklib/lib/puppet/util/openstack.rb @@ -5,27 +5,46 @@ def self.add_openstack_type_methods(type, comment) type.newparam(:auth) do desc < { + 'username' => 'test', + 'password' => 'changeme', + 'project_name' => 'test', + 'auth_url' => 'http://localhost:35357/v2.0' +} + +or altenatively for Keystone API V3: auth => { - 'username' => 'test', - 'password' => 'passw0rd', - 'tenant_name' => 'test', - 'auth_url' => 'http://localhost:35357/v2.0', + 'username' => 'test', + 'password' => 'changeme', + 'project_name' => 'test', + 'project_domain_name' => 'domain1', + 'user_domain_name' => 'domain1', + 'auth_url' => 'http://localhost:35357/v3' } -or a path to an openrc file containing these credentials, e.g.: +2. Using a path to an openrc file containing these credentials auth => { - 'openrc' => '/root/openrc', + 'openrc' => '/root/openrc' } -or a service token and host, e.g.: +3. Using a service token + +For Keystone API V2: +auth => { + 'token' => 'example', + 'url' => 'http://localhost:35357/v2.0' +} +Alternatively for Keystone API V3: auth => { - 'service_token' => 'ADMIN', - 'auth_url' => 'http://localhost:35357/v2.0', + 'token' => 'example', + 'url' => 'http://localhost:35357/v3.0' } If not present, the provider will look for environment variables for diff --git a/openstacklib/manifests/wsgi/apache.pp b/openstacklib/manifests/wsgi/apache.pp index 9baf1cb4f..3b497ff7d 100644 --- a/openstacklib/manifests/wsgi/apache.pp +++ b/openstacklib/manifests/wsgi/apache.pp @@ -99,7 +99,7 @@ # (optional) Name of the WSGI daemon process. # Defaults to $name # -# [*wsgi_daemon_group*] +# [*wsgi_process_group*] # (optional) Name of the WSGI process group. # Defaults to $name # @@ -170,7 +170,7 @@ } $wsgi_daemon_process_options = { - owner => $user, + user => $user, group => $group, processes => $workers, threads => $threads, diff --git a/openstacklib/spec/defines/openstacklib_wsgi_apache_spec.rb b/openstacklib/spec/defines/openstacklib_wsgi_apache_spec.rb index 3fc529d04..15bd3f0b4 100644 --- a/openstacklib/spec/defines/openstacklib_wsgi_apache_spec.rb +++ b/openstacklib/spec/defines/openstacklib_wsgi_apache_spec.rb @@ -65,17 +65,23 @@ )} it { is_expected.to contain_apache__vhost('keystone_wsgi').with( - 'servername' => 'some.host.tld', - 'ip' => nil, - 'port' => '5000', - 'docroot' => '/var/www/cgi-bin/keystone', - 'docroot_owner' => 'keystone', - 'docroot_group' => 'keystone', - 'ssl' => 'true', - 'wsgi_daemon_process' => 'keystone_wsgi', - 'wsgi_process_group' => 'keystone_wsgi', - 'wsgi_script_aliases' => { '/' => "/var/www/cgi-bin/keystone/main" }, - 'require' => 'File[keystone_wsgi]' + 'servername' => 'some.host.tld', + 'ip' => nil, + 'port' => '5000', + 'docroot' => '/var/www/cgi-bin/keystone', + 'docroot_owner' => 'keystone', + 'docroot_group' => 'keystone', + 'ssl' => 'true', + 'wsgi_daemon_process' => 'keystone_wsgi', + 'wsgi_process_group' => 'keystone_wsgi', + 'wsgi_script_aliases' => { '/' => "/var/www/cgi-bin/keystone/main" }, + 'wsgi_daemon_process_options' => { + 'user' => 'keystone', + 'group' => 'keystone', + 'processes' => 1, + 'threads' => global_facts[:processorcount], + }, + 'require' => 'File[keystone_wsgi]' )} it { is_expected.to contain_file("#{platform_parameters[:httpd_ports_file]}") } end diff --git a/openstacklib/spec/unit/provider/openstack_spec.rb b/openstacklib/spec/unit/provider/openstack_spec.rb index c5f5efe13..558c49086 100644 --- a/openstacklib/spec/unit/provider/openstack_spec.rb +++ b/openstacklib/spec/unit/provider/openstack_spec.rb @@ -8,10 +8,10 @@ describe Puppet::Provider::Openstack do before(:each) do - ENV['OS_USERNAME'] = nil - ENV['OS_PASSWORD'] = nil - ENV['OS_TENANT_NAME'] = nil - ENV['OS_AUTH_URL'] = nil + ENV['OS_USERNAME'] = nil + ENV['OS_PASSWORD'] = nil + ENV['OS_PROJECT_NAME'] = nil + ENV['OS_AUTH_URL'] = nil end let(:type) do @@ -22,12 +22,36 @@ end end - shared_examples 'authenticating with environment variables' do + shared_examples 'authenticating with environment variables using API v2' do it 'makes a successful request' do - ENV['OS_USERNAME'] = 'test' - ENV['OS_PASSWORD'] = 'abc123' - ENV['OS_TENANT_NAME'] = 'test' - ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' + if provider.class == Class + provider.stubs(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) + .returns('"ID","Name","Description","Enabled" +"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True +') + else + provider.class.stubs(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) + .returns('"ID","Name","Description","Enabled" +"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True +') + end + response = provider.request('project', 'list', nil, nil, '--long' ) + expect(response.first[:description]).to match /Test tenant/ + end + end + + shared_examples 'authenticating with environment variables using API v3' do + it 'makes a successful request' do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' if provider.class == Class provider.stubs(:openstack) .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) @@ -59,10 +83,10 @@ { :name => 'stubresource', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'test', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'test', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -72,7 +96,7 @@ it 'makes a successful request' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True ') @@ -82,7 +106,7 @@ end context 'with valid openrc file in parameters' do - mock = "export OS_USERNAME='test'\nexport OS_PASSWORD='abc123'\nexport OS_TENANT_NAME='test'\nexport OS_AUTH_URL='http://127.0.0.1:5000/v2.0'" + mock = "export OS_USERNAME='test'\nexport OS_PASSWORD='abc123'\nexport OS_PROJECT_NAME='test'\nexport OS_AUTH_URL='http://127.0.0.1:5000/v2.0'" let(:resource_attrs) do { :name => 'stubresource', @@ -98,7 +122,7 @@ it 'makes a successful request' do File.expects(:open).with('/root/openrc').returns(StringIO.new(mock)) provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True ') @@ -113,7 +137,7 @@ :name => 'stubresource', :auth => { 'token' => 'secrettoken', - 'auth_url' => 'http://127.0.0.1:5000/v2.0' + 'url' => 'http://127.0.0.1:5000/v2.0' } } end @@ -149,7 +173,7 @@ end context 'with valid password credentials in environment variables' do - it_behaves_like 'authenticating with environment variables' do + it_behaves_like 'authenticating with environment variables using API v2' do let(:resource_attrs) do { :name => 'stubresource', @@ -179,10 +203,10 @@ { :name => 'stubresource', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'test', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'test', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -191,7 +215,7 @@ end it 'retries' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .raises(Puppet::ExecutionFailure, 'Unable to establish connection') .then .returns('') @@ -205,7 +229,7 @@ describe '::request' do context 'with valid password credentials in environment variables' do - it_behaves_like 'authenticating with environment variables' do + it_behaves_like 'authenticating with environment variables using API v2' do let(:resource_attrs) do { :name => 'stubresource', diff --git a/rabbitmq/README.md b/rabbitmq/README.md index 7471a72fb..2b88d2f51 100644 --- a/rabbitmq/README.md +++ b/rabbitmq/README.md @@ -224,7 +224,8 @@ This value has no default and must be set explicitly if using clustering. ####`file_limit` -Set rabbitmq file ulimit. Defaults to 16384. Only available on systems with `$::osfamily == 'Debian'` +Set rabbitmq file ulimit. Defaults to 16384. Only available on systems with +`$::osfamily == 'Debian'` or `$::osfamily == 'RedHat'`. ####`key_content` diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb b/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb index e0eebd025..e1b06b419 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb @@ -90,6 +90,8 @@ def create vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", + '-c', + '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{name}", "destination=#{destination}", "arguments=#{arguments.to_json}", @@ -103,7 +105,7 @@ def destroy vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' name = resource[:name].split('@').first destination = resource[:name].split('@')[1] - rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}") + rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}") @property_hash[:ensure] = :absent end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb b/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb index b0ecb1f5a..eeffa953c 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb @@ -87,6 +87,8 @@ def create vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", + '-c', + '/etc/rabbitmq/rabbitmqadmin.conf', "name=#{name}", "durable=#{resource[:durable]}", "auto_delete=#{resource[:auto_delete]}", @@ -98,7 +100,7 @@ def create def destroy vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' name = resource[:name].rpartition('@').first - rabbitmqadmin('delete', 'queue', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}") + rabbitmqadmin('delete', 'queue', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "name=#{name}") @property_hash[:ensure] = :absent end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb index 3980e7556..da37886cb 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb @@ -45,8 +45,8 @@ def password def check_password - response = rabbitmqctl('eval', 'rabbit_auth_backend_internal:check_user_login(<<"' + resource[:name] + '">>, [{password, <<"' + resource[:password] +'">>}]).') - if response.include? 'invalid credentials' + response = rabbitmqctl('eval', 'rabbit_access_control:check_user_pass_login(list_to_binary("' + resource[:name] + '"), list_to_binary("' + resource[:password] +'")).') + if response.include? 'refused' false else true diff --git a/rabbitmq/manifests/config.pp b/rabbitmq/manifests/config.pp index a2fb56a7e..5e3f1ef6e 100644 --- a/rabbitmq/manifests/config.pp +++ b/rabbitmq/manifests/config.pp @@ -106,14 +106,48 @@ } } - if $::osfamily == 'Debian' { - file { '/etc/default/rabbitmq-server': - ensure => file, - content => template('rabbitmq/default.erb'), - mode => '0644', - owner => '0', - group => '0', - notify => Class['rabbitmq::service'], + case $::osfamily { + 'Debian': { + file { '/etc/default/rabbitmq-server': + ensure => file, + content => template('rabbitmq/default.erb'), + mode => '0644', + owner => '0', + group => '0', + notify => Class['rabbitmq::service'], + } + } + 'RedHat': { + if versioncmp($::operatingsystemmajrelease, '7') >= 0 { + file { '/etc/systemd/system/rabbitmq-server.service.d': + ensure => directory, + owner => '0', + group => '0', + mode => '0755', + } -> + file { '/etc/systemd/system/rabbitmq-server.service.d/limits.conf': + content => template('rabbitmq/rabbitmq-server.service.d/limits.conf'), + owner => '0', + group => '0', + mode => '0644', + notify => Exec['rabbitmq-systemd-reload'], + } + exec { 'rabbitmq-systemd-reload': + command => '/usr/bin/systemctl daemon-reload', + notify => Class['Rabbitmq::Service'], + refreshonly => true, + } + } else { + file { '/etc/security/limits.d/rabbitmq-server.conf': + content => template('rabbitmq/limits.conf'), + owner => '0', + group => '0', + mode => '0644', + notify => Class['Rabbitmq::Service'], + } + } + } + default: { } } diff --git a/rabbitmq/manifests/init.pp b/rabbitmq/manifests/init.pp index 5946fe57d..4e115f9b2 100644 --- a/rabbitmq/manifests/init.pp +++ b/rabbitmq/manifests/init.pp @@ -200,10 +200,9 @@ include '::rabbitmq::install::rabbitmqadmin' rabbitmq_plugin { 'rabbitmq_management': - ensure => present, - require => Class['rabbitmq::install'], - notify => Class['rabbitmq::service'], - provider => 'rabbitmqplugins' + ensure => present, + require => Class['rabbitmq::install'], + notify => Class['rabbitmq::service'], } Class['::rabbitmq::service'] -> Class['::rabbitmq::install::rabbitmqadmin'] @@ -212,19 +211,17 @@ if $stomp_ensure { rabbitmq_plugin { 'rabbitmq_stomp': - ensure => present, - require => Class['rabbitmq::install'], - notify => Class['rabbitmq::service'], - provider => 'rabbitmqplugins' + ensure => present, + require => Class['rabbitmq::install'], + notify => Class['rabbitmq::service'], } } if ($ldap_auth) { rabbitmq_plugin { 'rabbitmq_auth_backend_ldap': - ensure => present, - require => Class['rabbitmq::install'], - notify => Class['rabbitmq::service'], - provider => 'rabbitmqplugins', + ensure => present, + require => Class['rabbitmq::install'], + notify => Class['rabbitmq::service'], } } diff --git a/rabbitmq/spec/acceptance/queue_spec.rb b/rabbitmq/spec/acceptance/queue_spec.rb new file mode 100644 index 000000000..a1643a632 --- /dev/null +++ b/rabbitmq/spec/acceptance/queue_spec.rb @@ -0,0 +1,157 @@ +require 'spec_helper_acceptance' + +describe 'rabbitmq binding:' do + + + context "create binding and queue resources when rabbit using default management port" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_user { 'dan': + admin => true, + password => 'bar', + tags => ['monitoring', 'tag1'], + } -> + + rabbitmq_user_permissions { 'dan@host1': + configure_permission => '.*', + read_permission => '.*', + write_permission => '.*', + } + + rabbitmq_vhost { 'host1': + ensure => present, + } -> + + rabbitmq_exchange { 'exchange1@host1': + user => 'dan', + password => 'bar', + type => 'topic', + ensure => present, + } -> + + rabbitmq_queue { 'queue1@host1': + user => 'dan', + password => 'bar', + durable => true, + auto_delete => false, + ensure => present, + } -> + + rabbitmq_binding { 'exchange1@queue1@host1': + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => '#', + ensure => present, + } + + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the binding' do + shell('rabbitmqctl list_bindings -q -p host1') do |r| + expect(r.stdout).to match(/exchange1\sexchange\squeue1\squeue\s#/) + expect(r.exit_code).to be_zero + end + end + + it 'should have the queue' do + shell('rabbitmqctl list_queues -q -p host1') do |r| + expect(r.stdout).to match(/queue1/) + expect(r.exit_code).to be_zero + end + end + + end + + context "create binding and queue resources when rabbit using a non-default management port" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + management_port => '11111', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_user { 'dan': + admin => true, + password => 'bar', + tags => ['monitoring', 'tag1'], + } -> + + rabbitmq_user_permissions { 'dan@host2': + configure_permission => '.*', + read_permission => '.*', + write_permission => '.*', + } + + rabbitmq_vhost { 'host2': + ensure => present, + } -> + + rabbitmq_exchange { 'exchange2@host2': + user => 'dan', + password => 'bar', + type => 'topic', + ensure => present, + } -> + + rabbitmq_queue { 'queue2@host2': + user => 'dan', + password => 'bar', + durable => true, + auto_delete => false, + ensure => present, + } -> + + rabbitmq_binding { 'exchange2@queue2@host2': + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => '#', + ensure => present, + } + + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the binding' do + shell('rabbitmqctl list_bindings -q -p host2') do |r| + expect(r.stdout).to match(/exchange2\sexchange\squeue2\squeue\s#/) + expect(r.exit_code).to be_zero + end + end + + it 'should have the queue' do + shell('rabbitmqctl list_queues -q -p host2') do |r| + expect(r.stdout).to match(/queue2/) + expect(r.exit_code).to be_zero + end + end + + end + +end diff --git a/rabbitmq/spec/classes/rabbitmq_spec.rb b/rabbitmq/spec/classes/rabbitmq_spec.rb index 6ddc26f25..47a5c9860 100644 --- a/rabbitmq/spec/classes/rabbitmq_spec.rb +++ b/rabbitmq/spec/classes/rabbitmq_spec.rb @@ -248,6 +248,144 @@ end end + context 'on RedHat 7.0 or more' do + let(:facts) {{ :osfamily => 'RedHat', :operatingsystemmajrelease => '7' }} + + it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d').with( + 'ensure' => 'directory', + 'owner' => '0', + 'group' => '0', + 'mode' => '0755' + ) } + + it { should contain_exec('rabbitmq-systemd-reload').with( + 'command' => '/usr/bin/systemctl daemon-reload', + 'notify' => 'Class[Rabbitmq::Service]', + 'refreshonly' => true + ) } + context 'with file_limit => unlimited' do + let(:params) {{ :file_limit => 'unlimited' }} + it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Exec[rabbitmq-systemd-reload]', + 'content' => '[Service] +LimitNOFILE=unlimited +' + ) } + end + + context 'with file_limit => infinity' do + let(:params) {{ :file_limit => 'infinity' }} + it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Exec[rabbitmq-systemd-reload]', + 'content' => '[Service] +LimitNOFILE=infinity +' + ) } + end + + context 'with file_limit => -1' do + let(:params) {{ :file_limit => -1 }} + it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Exec[rabbitmq-systemd-reload]', + 'content' => '[Service] +LimitNOFILE=-1 +' + ) } + end + + context 'with file_limit => \'1234\'' do + let(:params) {{ :file_limit => '1234' }} + it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Exec[rabbitmq-systemd-reload]', + 'content' => '[Service] +LimitNOFILE=1234 +' + ) } + end + + context 'with file_limit => foo' do + let(:params) {{ :file_limit => 'foo' }} + it 'does not compile' do + expect { catalogue }.to raise_error(Puppet::Error, /\$file_limit must be an integer, 'unlimited', or 'infinity'/) + end + end + end + + context 'on RedHat before 7.0' do + let(:facts) {{ :osfamily => 'RedHat', :operatingsystemmajrelease => '6' }} + + context 'with file_limit => unlimited' do + let(:params) {{ :file_limit => 'unlimited' }} + it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Class[Rabbitmq::Service]', + 'content' => 'rabbitmq soft nofile unlimited +rabbitmq hard nofile unlimited +' + ) } + end + + context 'with file_limit => infinity' do + let(:params) {{ :file_limit => 'infinity' }} + it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Class[Rabbitmq::Service]', + 'content' => 'rabbitmq soft nofile infinity +rabbitmq hard nofile infinity +' + ) } + end + + context 'with file_limit => -1' do + let(:params) {{ :file_limit => -1 }} + it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Class[Rabbitmq::Service]', + 'content' => 'rabbitmq soft nofile -1 +rabbitmq hard nofile -1 +' + ) } + end + + context 'with file_limit => \'1234\'' do + let(:params) {{ :file_limit => '1234' }} + it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644', + 'notify' => 'Class[Rabbitmq::Service]', + 'content' => 'rabbitmq soft nofile 1234 +rabbitmq hard nofile 1234 +' + ) } + end + + context 'with file_limit => foo' do + let(:params) {{ :file_limit => 'foo' }} + it 'does not compile' do + expect { catalogue }.to raise_error(Puppet::Error, /\$file_limit must be an integer, 'unlimited', or 'infinity'/) + end + end + end + ['Debian', 'RedHat', 'SUSE', 'Archlinux'].each do |distro| context "on #{distro}" do let(:facts) {{ diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb index d1ff0667c..50594efee 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb @@ -28,12 +28,12 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination=target', 'arguments={}', 'routing_key=blablub', 'destination_type=queue') + @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=source', 'destination=target', 'arguments={}', 'routing_key=blablub', 'destination_type=queue') @provider.create end it 'should call rabbitmqadmin to destroy' do - @provider.expects(:rabbitmqadmin).with('delete', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination_type=queue', 'destination=target') + @provider.expects(:rabbitmqadmin).with('delete', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=source', 'destination_type=queue', 'destination=target') @provider.destroy end @@ -52,7 +52,7 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=colin', '--password=secret', 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue') + @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=colin', '--password=secret', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue') @provider.create end end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb index 97410a8b4..85843da8a 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb @@ -29,12 +29,12 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=guest', '--password=guest', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') + @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') @provider.create end it 'should call rabbitmqadmin to destroy' do - @provider.expects(:rabbitmqadmin).with('delete', 'queue', '--vhost=/', '--user=guest', '--password=guest', 'name=test') + @provider.expects(:rabbitmqadmin).with('delete', 'queue', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test') @provider.destroy end @@ -53,7 +53,7 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=colin', '--password=secret', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') + @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=colin', '--password=secret', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') @provider.create end end diff --git a/rabbitmq/templates/limits.conf b/rabbitmq/templates/limits.conf new file mode 100644 index 000000000..bb017fd9c --- /dev/null +++ b/rabbitmq/templates/limits.conf @@ -0,0 +1,2 @@ +rabbitmq soft nofile <%= @file_limit %> +rabbitmq hard nofile <%= @file_limit %> diff --git a/rabbitmq/templates/rabbitmq-server.service.d/limits.conf b/rabbitmq/templates/rabbitmq-server.service.d/limits.conf new file mode 100644 index 000000000..78773864e --- /dev/null +++ b/rabbitmq/templates/rabbitmq-server.service.d/limits.conf @@ -0,0 +1,2 @@ +[Service] +LimitNOFILE=<%= @file_limit %> diff --git a/rsync/manifests/server.pp b/rsync/manifests/server.pp index 65804c189..30d9b11e2 100644 --- a/rsync/manifests/server.pp +++ b/rsync/manifests/server.pp @@ -17,8 +17,13 @@ $conf_file = $::osfamily ? { 'Debian' => '/etc/rsyncd.conf', + 'suse' => '/etc/rsyncd.conf', default => '/etc/rsync.conf', } + $servicename = $::osfamily ? { + 'suse' => 'rsyncd', + default => 'rsync', + } if $use_xinetd { include xinetd @@ -30,7 +35,7 @@ require => Package['rsync'], } } else { - service { 'rsync': + service { $servicename: ensure => running, enable => true, hasstatus => true, diff --git a/rsync/metadata.json b/rsync/metadata.json index 7187040f3..e88c08b8b 100644 --- a/rsync/metadata.json +++ b/rsync/metadata.json @@ -8,7 +8,7 @@ "project_page": "https://github.com/puppetlabs/puppetlabs-rsync", "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", "dependencies": [ - {"name":"puppetlabs/stdlib","version_requirement":">=2.2.1"}, + {"name":"puppetlabs/stdlib","version_requirement":">=4.2.0"}, {"name":"puppetlabs/xinetd","version_requirement":">=1.1.0"}, {"name":"puppetlabs/concat","version_requirement":">= 1.1.1"} ] diff --git a/rsync/spec/classes/server_spec.rb b/rsync/spec/classes/server_spec.rb index 0b52ce5fe..19ad7a977 100644 --- a/rsync/spec/classes/server_spec.rb +++ b/rsync/spec/classes/server_spec.rb @@ -82,4 +82,19 @@ } end + describe 'on SuSE, use_xinetd => false' do + let(:params) do + { + :use_xinetd => false, + } + end + let(:facts) do + { + :osfamily => 'SuSE', + :concat_basedir => '/dne', + } + end + + it{ is_expected.to contain_service('rsyncd') } + end end diff --git a/sahara/.fixtures.yml b/sahara/.fixtures.yml index edced99dc..9274e7292 100644 --- a/sahara/.fixtures.yml +++ b/sahara/.fixtures.yml @@ -1,7 +1,9 @@ fixtures: repositories: 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' - 'concat': 'git://github.com/puppetlabs/puppetlabs-concat.git' + 'concat': + repo: 'git://github.com/puppetlabs/puppetlabs-concat.git' + ref: '1.2.1' 'keystone': 'git://github.com/stackforge/puppet-keystone.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' 'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git' diff --git a/sahara/LICENSE b/sahara/LICENSE index d9a10c0d8..88a11a0e7 100644 --- a/sahara/LICENSE +++ b/sahara/LICENSE @@ -1,176 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2012 OpenStack Foundation - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +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 - 1. Definitions. + http://www.apache.org/licenses/LICENSE-2.0 - "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 +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/sahara/manifests/notify/rabbitmq.pp b/sahara/manifests/notify/rabbitmq.pp index 54791918e..1cb2a7cd0 100644 --- a/sahara/manifests/notify/rabbitmq.pp +++ b/sahara/manifests/notify/rabbitmq.pp @@ -105,29 +105,37 @@ $kombu_reconnect_delay = '1.0', ) { if $rabbit_use_ssl { - if !$kombu_ssl_keyfile { - fail('kombu_ssl_keyfile must be set when using SSL in rabbit') - } - if !$kombu_ssl_certfile { - fail('kombu_ssl_certfile must be set when using SSL in rabbit') + + if $kombu_ssl_ca_certs { + sahara_config { 'DEFAULT/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs; } + } else { + sahara_config { 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; } } - if !$kombu_ssl_ca_certs { - fail('kombu_ssl_ca_certs must be set when using SSL in rabbit') + + if $kombu_ssl_certfile or $kombu_ssl_keyfile { + sahara_config { + 'DEFAULT/kombu_ssl_certfile': value => $kombu_ssl_certfile; + 'DEFAULT/kombu_ssl_keyfile': value => $kombu_ssl_keyfile; + } + } else { + sahara_config { + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + } } - sahara_config { - 'DEFAULT/kombu_ssl_version': value => $kombu_ssl_version; - 'DEFAULT/kombu_ssl_keyfile': value => $kombu_ssl_keyfile; - 'DEFAULT/kombu_ssl_certfile': value => $kombu_ssl_certfile; - 'DEFAULT/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs; - 'DEFAULT/kombu_reconnect_delay': value => $kombu_reconnect_delay; + + if $kombu_ssl_version { + sahara_config { 'DEFAULT/kombu_ssl_version': value => $kombu_ssl_version; } + } else { + sahara_config { 'DEFAULT/kombu_ssl_version': ensure => absent; } } + } else { sahara_config { - 'DEFAULT/kombu_ssl_version': ensure => absent; - 'DEFAULT/kombu_ssl_keyfile': ensure => absent; - 'DEFAULT/kombu_ssl_certfile': ensure => absent; 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; - 'DEFAULT/kombu_reconnect_delay': ensure => absent; + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'DEFAULT/kombu_ssl_version': ensure => absent; } } @@ -161,5 +169,6 @@ 'DEFAULT/rabbit_max_retries': value => $rabbit_max_retries; 'DEFAULT/notification_topics': value => $notification_topics; 'DEFAULT/control_exchange': value => $control_exchange; + 'DEFAULT/kombu_reconnect_delay': value => $kombu_reconnect_delay; } } diff --git a/sahara/spec/classes/sahara_notify_rabbitmq_spec.rb b/sahara/spec/classes/sahara_notify_rabbitmq_spec.rb index eb4f5dbd3..40cdc67f6 100644 --- a/sahara/spec/classes/sahara_notify_rabbitmq_spec.rb +++ b/sahara/spec/classes/sahara_notify_rabbitmq_spec.rb @@ -57,6 +57,18 @@ it { is_expected.to contain_sahara_config('DEFAULT/kombu_ssl_version').with_value('TLSv1') } end + describe 'with rabbit ssl cert parameters' do + let :params do + { + :rabbit_password => 'pass', + :rabbit_use_ssl => 'true', + } + end + + it { is_expected.to contain_sahara_config('DEFAULT/rabbit_use_ssl').with_value('true') } + it { is_expected.to contain_sahara_config('DEFAULT/kombu_ssl_version').with_value('TLSv1') } + end + describe 'with rabbit ssl disabled' do let :params do { diff --git a/stdlib/.travis.yml b/stdlib/.travis.yml index 503e1844d..b29f7e782 100644 --- a/stdlib/.travis.yml +++ b/stdlib/.travis.yml @@ -6,13 +6,19 @@ script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake matrix: fast_finish: true include: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.4.0" - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.6.0" - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.7.0" + env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.0.0 + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.4.0" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" notifications: email: false diff --git a/stdlib/CHANGELOG.md b/stdlib/CHANGELOG.md index 138569507..c17e7509a 100644 --- a/stdlib/CHANGELOG.md +++ b/stdlib/CHANGELOG.md @@ -1,17 +1,32 @@ -##2015-01-14 - Supported Release 4.6.0 +##2015-04-14 - Supported Release 4.6.0 ###Summary -Improved functionality and preparing for Puppet Next with new parser +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 function added to have Ruby File.basename functionality -- delete function can now take an array of items to remove -- MODULES-1473: deprecate type function in favor of type_of +- 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 time 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 -- Several test case fixes -- Ensure_resource is more verbose on debug mode +- 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 diff --git a/stdlib/README.markdown b/stdlib/README.markdown index 293a81aca..38890882a 100644 --- a/stdlib/README.markdown +++ b/stdlib/README.markdown @@ -244,6 +244,23 @@ This function flattens any deeply nested arrays and returns a single flat array Returns the largest integer less than or equal to the argument. Takes a single numeric value as an 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 a random number of times based on a node's fqdn. *Type*: rvalue @@ -500,6 +517,24 @@ Calling the class or definition from outside the current module will fail. For e *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. + +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` When given range in the form of '(start, stop)', `range` extrapolates a range as an array. 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]. diff --git a/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb b/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb new file mode 100644 index 000000000..2bb1287e0 --- /dev/null +++ b/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/stdlib/lib/puppet/parser/functions/loadyaml.rb b/stdlib/lib/puppet/parser/functions/loadyaml.rb index 10c400501..ca655f6ea 100644 --- a/stdlib/lib/puppet/parser/functions/loadyaml.rb +++ b/stdlib/lib/puppet/parser/functions/loadyaml.rb @@ -13,7 +13,12 @@ module Puppet::Parser::Functions raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)") end - YAML.load_file(args[0]) + if File.exists?(args[0]) then + YAML.load_file(args[0]) + else + warning("Can't load " + args[0] + ". File does not exist!") + nil + end end diff --git a/stdlib/lib/puppet/parser/functions/pw_hash.rb b/stdlib/lib/puppet/parser/functions/pw_hash.rb new file mode 100644 index 000000000..ad3e39375 --- /dev/null +++ b/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? + + # handle weak implementations of String#crypt + if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.' + # JRuby < 1.7.17 + if RUBY_PLATFORM == 'java' + # override String#crypt for password variable + def password.crypt(salt) + # puppetserver bundles Apache Commons Codec + org.apache.commons.codec.digest.Crypt.crypt(self.to_java_bytes, salt) + end + else + # MS Windows and other systems that don't support enhanced salts + raise Puppet::ParseError, 'system does not support enhanced salts' + end + end + password.crypt("$#{hash_type}$#{args[2]}") +end diff --git a/stdlib/lib/puppet/provider/file_line/ruby.rb b/stdlib/lib/puppet/provider/file_line/ruby.rb index ae1a8b3db..e7854f001 100644 --- a/stdlib/lib/puppet/provider/file_line/ruby.rb +++ b/stdlib/lib/puppet/provider/file_line/ruby.rb @@ -34,13 +34,22 @@ def lines def handle_create_with_match() regex = resource[:match] ? Regexp.new(resource[:match]) : nil + regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil match_count = count_matches(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(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) @@ -78,7 +87,10 @@ def count_matches(regex) # # @api private def append_line - File.open(resource[:path], 'a') do |fh| + File.open(resource[:path], 'w') do |fh| + lines.each do |l| + fh.puts(l) + end fh.puts resource[:line] end end diff --git a/stdlib/lib/puppet/type/file_line.rb b/stdlib/lib/puppet/type/file_line.rb index df263e6a7..29f95382a 100644 --- a/stdlib/lib/puppet/type/file_line.rb +++ b/stdlib/lib/puppet/type/file_line.rb @@ -3,9 +3,9 @@ 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 add the line to - ensure the desired state. Multiple resources may be declared to manage - multiple lines in the same file. + 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: @@ -13,6 +13,7 @@ path => '/etc/sudoers', line => '%sudo ALL=(ALL) ALL', } + file_line { 'sudo_rule_nopw': path => '/etc/sudoers', line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', @@ -21,6 +22,18 @@ 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. + **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. @@ -36,12 +49,15 @@ end newparam(:match) do - desc 'An optional regular expression to run against existing lines in the file;\n' + - 'if a match is found, we replace that line rather than adding a new line.' + 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 comparisson is performed against the line value and if it does not' + + ' match an exception will be raised. ' end newparam(:multiple) do - desc 'An optional value to determine if match can change multiple lines.' + 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 @@ -50,7 +66,7 @@ end newparam(:line) do - desc 'The line to be appended to the file located by the path parameter.' + desc 'The line to be appended to the file or used to replace matches found by the match attribute.' end newparam(:path) do diff --git a/stdlib/metadata.json b/stdlib/metadata.json index 27def9c08..51b73f78f 100644 --- a/stdlib/metadata.json +++ b/stdlib/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.5.1", + "version": "4.6.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", diff --git a/stdlib/spec/acceptance/fqdn_rand_string_spec.rb b/stdlib/spec/acceptance/fqdn_rand_string_spec.rb new file mode 100644 index 000000000..8fe1a6955 --- /dev/null +++ b/stdlib/spec/acceptance/fqdn_rand_string_spec.rb @@ -0,0 +1,60 @@ +#! /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 + let(:facts_d) do + if fact('is_pe', '--puppet') == "true" + 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 + else + '/etc/puppetlabs/facter/facts.d' + end + else + '/etc/facter/facts.d' + end + end + after :each do + shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") + 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 + it 'generates random alphanumeric strings' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $o = fqdn_rand_string($l) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) + end + end + it 'generates random alphanumeric strings with custom seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $s = 'seed' + $o = fqdn_rand_string($l, undef, $s) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles non-numbers for length argument' + end +end diff --git a/stdlib/spec/acceptance/pw_hash_spec.rb b/stdlib/spec/acceptance/pw_hash_spec.rb new file mode 100644 index 000000000..eddb78288 --- /dev/null +++ b/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']).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/stdlib/spec/functions/fqdn_rand_string_spec.rb b/stdlib/spec/functions/fqdn_rand_string_spec.rb new file mode 100644 index 000000000..949d930c7 --- /dev/null +++ b/stdlib/spec/functions/fqdn_rand_string_spec.rb @@ -0,0 +1,91 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the fqdn_rand_string function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("fqdn_rand_string")).to eq("function_fqdn_rand_string") + end + + it "should raise an ArgumentError if there is less than 1 argument" do + expect { fqdn_rand_string() }.to( raise_error(ArgumentError, /wrong number of arguments/)) + end + + it "should raise an ArgumentError if argument 1 isn't a positive integer" do + expect { fqdn_rand_string(0) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + expect { fqdn_rand_string(-1) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + expect { fqdn_rand_string(0.5) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + end + + it "provides a valid alphanumeric string when no character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length).match(string)).not_to eq(nil) + end + + it "provides a valid alphanumeric string when an undef character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => nil).match(string)).not_to eq(nil) + end + + it "provides a valid alphanumeric string when an empty character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => '').match(string)).not_to eq(nil) + end + + it "uses a provided character set" do + length = 100 + charset = '!@#$%^&*()-_=+' + string = %r{\A[#{charset}]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => charset).match(string)).not_to eq(nil) + end + + it "provides a random string exactly as long as the given length" do + expect(fqdn_rand_string(10).size).to eql(10) + end + + 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] || [] + + scope = PuppetlabsSpec::PuppetInternals.scope + scope.stubs(:[]).with("::fqdn").returns(host) + 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/stdlib/spec/functions/loadyaml_spec.rb b/stdlib/spec/functions/loadyaml_spec.rb index cdc3d6f51..4b8d40623 100755 --- a/stdlib/spec/functions/loadyaml_spec.rb +++ b/stdlib/spec/functions/loadyaml_spec.rb @@ -14,6 +14,12 @@ expect { scope.function_loadyaml([]) }.to raise_error(Puppet::ParseError) end + it "should return nil when file does not exist" do + yaml_file = tmpfilename ('yamlfile') + result = scope.function_loadyaml([yaml_file]) + expect(result).to(eq(nil)) + end + it "should convert YAML file to a data structure" do yaml_file = tmpfilename ('yamlfile') File.open(yaml_file, 'w') do |fh| diff --git a/stdlib/spec/functions/pw_hash_spec.rb b/stdlib/spec/functions/pw_hash_spec.rb new file mode 100644 index 000000000..337809085 --- /dev/null +++ b/stdlib/spec/functions/pw_hash_spec.rb @@ -0,0 +1,96 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the pw_hash function" do + + before :all do + @enhanced_salts_supported = RUBY_PLATFORM == 'java' + end + + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("pw_hash")).to eq("function_pw_hash") + end + + it "should raise an ArgumentError if there are less than 3 arguments" do + expect { scope.function_pw_hash([]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + expect { scope.function_pw_hash(['password']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + expect { scope.function_pw_hash(['password', 'sha-512']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + end + + it "should raise an ArgumentError if there are more than 3 arguments" do + expect { scope.function_pw_hash(['password', 'sha-512', 'salt', 5]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + end + + it "should raise an ArgumentError if the first argument is not a string" do + expect { scope.function_pw_hash([['password'], 'sha-512', 'salt']) }.to( raise_error(ArgumentError, /first argument must be a string/) ) + # in Puppet 3, numbers are passed as strings, so we can't test that + end + + it "should return nil if the first argument is empty" do + expect(scope.function_pw_hash(['', 'sha-512', 'salt'])).to eq(nil) + end + + it "should return nil if the first argument is undef" do + expect(scope.function_pw_hash([nil, 'sha-512', 'salt'])).to eq(nil) + end + + it "should raise an ArgumentError if the second argument is an invalid hash type" do + expect { scope.function_pw_hash(['', 'invalid', 'salt']) }.to( raise_error(ArgumentError, /not a valid hash type/) ) + end + + it "should raise an ArgumentError if the second argument is not a string" do + expect { scope.function_pw_hash(['', [], 'salt']) }.to( raise_error(ArgumentError, /second argument must be a string/) ) + end + + it "should raise an ArgumentError if the third argument is not a string" do + expect { scope.function_pw_hash(['password', 'sha-512', ['salt']]) }.to( raise_error(ArgumentError, /third argument must be a string/) ) + # in Puppet 3, numbers are passed as strings, so we can't test that + end + + it "should raise an ArgumentError if the third argument is empty" do + expect { scope.function_pw_hash(['password', 'sha-512', '']) }.to( raise_error(ArgumentError, /third argument must not be empty/) ) + end + + it "should raise an ArgumentError if the third argument has invalid characters" do + expect { scope.function_pw_hash(['password', 'sha-512', '%']) }.to( raise_error(ArgumentError, /characters in salt must be in the set/) ) + end + + it "should fail on platforms with weak implementations of String#crypt" do + String.any_instance.expects(:crypt).with('$1$1').returns('$1SoNol0Ye6Xk') + expect { scope.function_pw_hash(['password', 'sha-512', 'salt']) }.to( raise_error(Puppet::ParseError, /system does not support enhanced salts/) ) + end + + if @enhanced_salts_supported + describe "on systems with enhanced salts support" do + it "should return a hashed password" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end + + it "should use the specified salt" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to match('salt') + end + + it "should use the specified hash type" do + resultmd5 = scope.function_pw_hash(['password', 'md5', 'salt']) + resultsha256 = scope.function_pw_hash(['password', 'sha-256', 'salt']) + resultsha512 = scope.function_pw_hash(['password', 'sha-512', 'salt']) + + expect(resultmd5).to eql('$1$salt$qJH7.N4xYta3aEG/dfqo/0') + expect(resultsha256).to eql('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') + expect(resultsha512).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end + + it "should generate a valid hash" do + password_hash = scope.function_pw_hash(['password', 'sha-512', 'salt']) + + hash_parts = password_hash.match(%r{\A\$(.*)\$([a-zA-Z0-9./]+)\$([a-zA-Z0-9./]+)\z}) + + expect(hash_parts).not_to eql(nil) + end + end + end +end diff --git a/stdlib/spec/functions/validate_augeas_spec.rb b/stdlib/spec/functions/validate_augeas_spec.rb index c695ba2eb..99523ab77 100755 --- a/stdlib/spec/functions/validate_augeas_spec.rb +++ b/stdlib/spec/functions/validate_augeas_spec.rb @@ -60,7 +60,7 @@ end describe "Nicer Error Messages" do - # The intent here is to make sure the function returns the 3rd argument + # 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' ], @@ -69,7 +69,7 @@ inputs.each do |input| it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /#{input[2]}/ + expect { subject.call input }.to raise_error /#{input[3]}/ end end end diff --git a/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb b/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb index d2a129c32..a84fc78e7 100755 --- a/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -46,12 +46,12 @@ @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + } ) @provider = provider_class.new(@resource) end @@ -69,11 +69,11 @@ 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 + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :multiple => true, } ) @provider = provider_class.new(@resource) @@ -89,11 +89,11 @@ expect { @resource = Puppet::Type::File_line.new( { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => 'asgadga' + :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\./) @@ -140,7 +140,54 @@ 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| @@ -194,7 +241,12 @@ @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - {:name => 'foo', :path => @tmpfile, :line => 'foo', :ensure => 'absent' } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo', + :ensure => 'absent', + } ) @provider = provider_class.new(@resource) end diff --git a/swift/.fixtures.yml b/swift/.fixtures.yml index e503cd723..5b3af39a5 100644 --- a/swift/.fixtures.yml +++ b/swift/.fixtures.yml @@ -1,13 +1,17 @@ fixtures: repositories: "apt": "git://github.com/puppetlabs/puppetlabs-apt.git" - "concat": "git://github.com/puppetlabs/puppetlabs-concat.git" + "concat": + "repo": "git://github.com/puppetlabs/puppetlabs-concat.git" + "ref": "1.2.1" "inifile": "git://github.com/puppetlabs/puppetlabs-inifile" "keystone": "git://github.com/stackforge/puppet-keystone.git" "memcached": "git://github.com/saz/puppet-memcached.git" "openstacklib": "git://github.com/stackforge/puppet-openstacklib.git" "rsync": "git://github.com/puppetlabs/puppetlabs-rsync.git" - "ssh": "git://github.com/saz/puppet-ssh.git" + "ssh": + repo: "git://github.com/saz/puppet-ssh.git" + ref: "v2.4.0" "stdlib": "git://github.com/puppetlabs/puppetlabs-stdlib.git" "xinetd": "git://github.com/puppetlabs/puppetlabs-xinetd.git" symlinks: diff --git a/swift/LICENSE b/swift/LICENSE index 1c976ff23..88a11a0e7 100644 --- a/swift/LICENSE +++ b/swift/LICENSE @@ -1,8 +1,4 @@ -Puppet Labs Swift Module - Puppet module for managing Swift - -Copyright (C) 2012 Puppet Labs Inc - -Puppet Labs can be contacted at: info@puppetlabs.com +Copyright 2012 OpenStack Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/swift/lib/puppet/provider/swift_ring_builder.rb b/swift/lib/puppet/provider/swift_ring_builder.rb index 7a1bf45ba..2b30cc8bd 100644 --- a/swift/lib/puppet/provider/swift_ring_builder.rb +++ b/swift/lib/puppet/provider/swift_ring_builder.rb @@ -8,6 +8,14 @@ def self.instances end end + def self.address_string(address) + ip = IPAddr.new(address) + if ip.ipv6? + '[' + ip.to_s + ']' + else + ip.to_s + end + end def self.lookup_ring object_hash = {} @@ -30,7 +38,8 @@ def self.lookup_ring # Swift 1.8+ output example: if row =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\S+\s+\d+\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s*((-|\s-?)?\d+\.\d+)\s*(\S*)/ - object_hash["#{$4}:#{$5}/#{$6}"] = { + address = address_string("#{$4}") + object_hash["#{address}:#{$5}/#{$6}"] = { :id => $1, :region => $2, :zone => $3, @@ -43,7 +52,8 @@ def self.lookup_ring # Swift 1.8.0 output example: elsif row =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s*((-|\s-?)?\d+\.\d+)\s*(\S*)/ - object_hash["#{$4}:#{$5}/#{$6}"] = { + address = address_string("#{$4}") + object_hash["#{address}:#{$5}/#{$6}"] = { :id => $1, :region => $2, :zone => $3, @@ -55,7 +65,8 @@ def self.lookup_ring # This regex is for older swift versions elsif row =~ /^\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s+(-?\d+\.\d+)\s+(\S*)$/ - object_hash["#{$3}:#{$4}/#{$5}"] = { + address = address_string("#{$3}") + object_hash["#{address}:#{$4}/#{$5}"] = { :id => $1, :region => 'none', :zone => $2, diff --git a/swift/lib/puppet/type/ring_account_device.rb b/swift/lib/puppet/type/ring_account_device.rb index 5174f23d2..6882193a2 100644 --- a/swift/lib/puppet/type/ring_account_device.rb +++ b/swift/lib/puppet/type/ring_account_device.rb @@ -1,15 +1,19 @@ Puppet::Type.newtype(:ring_account_device) do require 'ipaddr' + require 'uri' ensurable newparam(:name, :namevar => true) do validate do |value| - address = value.split(':') - raise(Puppet::Error, "invalid name #{value}, should contain address:port/device") unless address.size == 2 - port_device = address[1].split('/') - raise(Puppet::Error, "namevar should contain a device") unless port_device.size == 2 - IPAddr.new(address[0]) + # we have to have URI Scheme so we just add http:// and ignore it later + uri = URI('http://' + value) + address = uri.host + port_device = uri.port + if ['','/'].include?(uri.path) + raise(Puppet::Error, "namevar should contain a device") + end + IPAddr.new(address) end end diff --git a/swift/lib/puppet/type/ring_container_device.rb b/swift/lib/puppet/type/ring_container_device.rb index 60144b068..2aec5edcf 100644 --- a/swift/lib/puppet/type/ring_container_device.rb +++ b/swift/lib/puppet/type/ring_container_device.rb @@ -1,15 +1,19 @@ Puppet::Type.newtype(:ring_container_device) do require 'ipaddr' + require 'uri' ensurable newparam(:name, :namevar => true) do validate do |value| - address = value.split(':') - raise(Puppet::Error, "invalid name #{value}, should contain address:port/device") unless address.size == 2 - port_device = address[1].split('/') - raise(Puppet::Error, "namevar should contain a device") unless port_device.size == 2 - IPAddr.new(address[0]) + # we have to have URI Scheme so we just add http:// and ignore it later + uri = URI('http://' + value) + address = uri.host + port_device = uri.port + if ['','/'].include?(uri.path) + raise(Puppet::Error, "namevar should contain a device") + end + IPAddr.new(address) end end diff --git a/swift/lib/puppet/type/ring_object_device.rb b/swift/lib/puppet/type/ring_object_device.rb index 2de2d806f..a977ce415 100644 --- a/swift/lib/puppet/type/ring_object_device.rb +++ b/swift/lib/puppet/type/ring_object_device.rb @@ -1,15 +1,19 @@ Puppet::Type.newtype(:ring_object_device) do require 'ipaddr' + require 'uri' ensurable newparam(:name, :namevar => true) do validate do |value| - address = value.split(':') - raise(Puppet::Error, "invalid name #{value}, should contain address:port/device") unless address.size == 2 - port_device = address[1].split('/') - raise(Puppet::Error, "namevar should contain a device") unless port_device.size == 2 - IPAddr.new(address[0]) + # we have to have URI Scheme so we just add http:// and ignore it later + uri = URI('http://' + value) + address = uri.host + port_device = uri.port + if ['','/'].include?(uri.path) + raise(Puppet::Error, "namevar should contain a device") + end + IPAddr.new(address) end end diff --git a/swift/manifests/client.pp b/swift/manifests/client.pp index 757a74785..088d97315 100644 --- a/swift/manifests/client.pp +++ b/swift/manifests/client.pp @@ -17,6 +17,7 @@ package { 'swiftclient': ensure => $ensure, name => $::swift::params::client_package, + tag => 'openstack', } } diff --git a/swift/manifests/init.pp b/swift/manifests/init.pp index 2163f3e5d..b6595eef5 100644 --- a/swift/manifests/init.pp +++ b/swift/manifests/init.pp @@ -39,6 +39,7 @@ package { 'swift': ensure => $package_ensure, name => $::swift::params::package_name, + tag => 'openstack', } } diff --git a/swift/manifests/proxy.pp b/swift/manifests/proxy.pp index 503a8d54a..c6613450e 100644 --- a/swift/manifests/proxy.pp +++ b/swift/manifests/proxy.pp @@ -135,6 +135,8 @@ include ::swift::params include ::concat::setup + Swift_config<| |> ~> Service['swift-proxy'] + validate_bool($account_autocreate) validate_bool($allow_account_management) validate_array($pipeline) @@ -164,6 +166,7 @@ package { 'swift-proxy': ensure => $package_ensure, name => $::swift::params::proxy_package_name, + tag => 'openstack', } concat { '/etc/swift/proxy-server.conf': diff --git a/swift/manifests/proxy/swift3.pp b/swift/manifests/proxy/swift3.pp index 5eecba4f5..dec0e0dea 100644 --- a/swift/manifests/proxy/swift3.pp +++ b/swift/manifests/proxy/swift3.pp @@ -29,6 +29,7 @@ package { 'swift-plugin-s3': ensure => $ensure, name => $::swift::params::swift3, + tag => 'openstack', } concat::fragment { 'swift_swift3': diff --git a/swift/manifests/storage/account.pp b/swift/manifests/storage/account.pp index 3a66d6783..72f130ca7 100644 --- a/swift/manifests/storage/account.pp +++ b/swift/manifests/storage/account.pp @@ -18,6 +18,10 @@ $enabled = true, $package_ensure = 'present' ) { + + Swift_config<| |> ~> Service['swift-account-reaper'] + Swift_config<| |> ~> Service['swift-account-auditor'] + swift::storage::generic { 'account': manage_service => $manage_service, enabled => $enabled, diff --git a/swift/manifests/storage/container.pp b/swift/manifests/storage/container.pp index f11bc03b8..aa054f526 100644 --- a/swift/manifests/storage/container.pp +++ b/swift/manifests/storage/container.pp @@ -23,6 +23,10 @@ $package_ensure = 'present', $allowed_sync_hosts = ['127.0.0.1'], ) { + + Swift_config<| |> ~> Service['swift-container-updater'] + Swift_config<| |> ~> Service['swift-container-auditor'] + swift::storage::generic { 'container': manage_service => $manage_service, enabled => $enabled, @@ -71,5 +75,6 @@ provider => $::swift::params::service_provider, require => File['/etc/init/swift-container-sync.conf', '/etc/init.d/swift-container-sync'], } + Swift_config<| |> ~> Service['swift-container-sync'] } } diff --git a/swift/manifests/storage/generic.pp b/swift/manifests/storage/generic.pp index 928d52e97..88948d01c 100644 --- a/swift/manifests/storage/generic.pp +++ b/swift/manifests/storage/generic.pp @@ -38,6 +38,7 @@ include ::swift::params Class['swift::storage'] -> Swift::Storage::Generic[$name] + Swift_config<| |> ~> Service["swift-${name}"] validate_re($name, '^object|container|account$') @@ -46,6 +47,7 @@ # this is a way to dynamically build the variables to lookup # sorry its so ugly :( name => inline_template("<%= scope.lookupvar('::swift::params::${name}_package_name') %>"), + tag => 'openstack', before => Service["swift-${name}", "swift-${name}-replicator"], } diff --git a/swift/manifests/storage/object.pp b/swift/manifests/storage/object.pp index 2055843df..243e0d97d 100644 --- a/swift/manifests/storage/object.pp +++ b/swift/manifests/storage/object.pp @@ -18,6 +18,10 @@ $enabled = true, $package_ensure = 'present' ) { + + Swift_config<| |> ~> Service['swift-object-updater'] + Swift_config<| |> ~> Service['swift-object-auditor'] + swift::storage::generic { 'object': manage_service => $manage_service, enabled => $enabled, diff --git a/swift/metadata.json b/swift/metadata.json index 6b1886470..0dfd0e06a 100644 --- a/swift/metadata.json +++ b/swift/metadata.json @@ -38,6 +38,6 @@ { "name": "puppetlabs/xinetd", "version_requirement": ">=1.0.1 <2.0.0" }, { "name": "puppetlabs/concat", "version_requirement": ">=1.0.0 <2.0.0" }, { "name": "saz/memcached", "version_requirement": ">=2.0.2 <3.0.0" }, - { "name": "saz/ssh", "version_requirement": ">=1.0.2 <2.0.0" } + { "name": "saz/ssh", "version_requirement": ">=2.0.0 <3.0.0" } ] } diff --git a/swift/spec/classes/swift_client_spec.rb b/swift/spec/classes/swift_client_spec.rb index 06e1e68fd..b4da0905e 100644 --- a/swift/spec/classes/swift_client_spec.rb +++ b/swift/spec/classes/swift_client_spec.rb @@ -1,20 +1,45 @@ require 'spec_helper' describe 'swift::client' do - it { is_expected.to contain_package('swiftclient').with( - :ensure => 'present', - :name => 'python-swiftclient' - )} - let :facts do - {:osfamily => 'Debian'} + + let :params do + {} + end + + let :default_params do + { :package_ensure => 'present' } + end + + shared_examples_for 'swift client' do + let :p do + default_params.merge(params) + end + + it { is_expected.to contain_class('swift::params') } + + it 'installs swift client package' do + is_expected.to contain_package('swiftclient').with( + :name => 'python-swiftclient', + :ensure => p[:package_ensure], + :tag => 'openstack' + ) + end + + end + + context 'on Debian platform' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'swift client' end - context 'with params' do - let :params do - {:ensure => 'latest'} + + context 'on RedHat platform' do + let :facts do + { :osfamily => 'RedHat' } end - it { is_expected.to contain_package('swiftclient').with( - :ensure => 'latest', - :name => 'python-swiftclient' - )} + + it_configures 'swift client' end end diff --git a/swift/spec/classes/swift_keystone_auth_spec.rb b/swift/spec/classes/swift_keystone_auth_spec.rb index 1e1e4960a..ecdf8c1e2 100644 --- a/swift/spec/classes/swift_keystone_auth_spec.rb +++ b/swift/spec/classes/swift_keystone_auth_spec.rb @@ -150,18 +150,18 @@ }) end it 'configures correct user name' do - should contain_keystone_user('swift') + is_expected.to contain_keystone_user('swift') end it 'configures correct user role' do - should contain_keystone_user_role('swift@services') + is_expected.to contain_keystone_user_role('swift@services') end it 'configures correct service name' do - should contain_keystone_service('swift_service') - should contain_keystone_service('swift_service_s3') + is_expected.to contain_keystone_service('swift_service') + is_expected.to contain_keystone_service('swift_service_s3') end it 'configures correct endpoint name' do - should contain_keystone_endpoint('RegionOne/swift_service') - should contain_keystone_endpoint('RegionOne/swift_service_s3') + is_expected.to contain_keystone_endpoint('RegionOne/swift_service') + is_expected.to contain_keystone_endpoint('RegionOne/swift_service_s3') end end diff --git a/swift/spec/defines/swift_storage_generic_spec.rb b/swift/spec/defines/swift_storage_generic_spec.rb index 77992c494..b63e8ed97 100644 --- a/swift/spec/defines/swift_storage_generic_spec.rb +++ b/swift/spec/defines/swift_storage_generic_spec.rb @@ -46,7 +46,10 @@ class { 'swift::storage': storage_local_net_ip => '10.0.0.1' }" let :params do param_set end - it { is_expected.to contain_package("swift-#{t}").with_ensure(param_hash[:package_ensure]) } + it { is_expected.to contain_package("swift-#{t}").with( + :ensure => param_hash[:package_ensure], + :tag => 'openstack' + )} it { is_expected.to contain_service("swift-#{t}").with( :ensure => 'running', :enable => true, diff --git a/swift/spec/unit/puppet/type/ring_account_device_spec.rb b/swift/spec/unit/puppet/type/ring_account_device_spec.rb index 98b3f0a49..11d5923ea 100644 --- a/swift/spec/unit/puppet/type/ring_account_device_spec.rb +++ b/swift/spec/unit/puppet/type/ring_account_device_spec.rb @@ -1,10 +1,9 @@ require 'puppet' describe Puppet::Type.type(:ring_account_device) do - - it 'should fail if the name has no ":"' do + it 'should fail if the name does not contain valid ipaddress' do expect { - Puppet::Type.type(:ring_account_device).new(:name => 'foo/bar') - }.to raise_error(Puppet::Error, /should contain address:port\/device/) + Puppet::Type.type(:ring_account_device).new(:name => '192.168.1.256:80/a') + }.to raise_error(Puppet::ResourceError, /invalid address/) end it 'should fail if the name does not contain a "/"' do diff --git a/swift/spec/unit/puppet/type/ring_container_device_spec.rb b/swift/spec/unit/puppet/type/ring_container_device_spec.rb index 80b436ab2..1b2cea8d1 100644 --- a/swift/spec/unit/puppet/type/ring_container_device_spec.rb +++ b/swift/spec/unit/puppet/type/ring_container_device_spec.rb @@ -1,16 +1,15 @@ require 'puppet' describe Puppet::Type.type(:ring_container_device) do - - it 'should fail if the name has no ":"' do + it 'should fail if the name does not contain valid ipaddress' do expect { - Puppet::Type.type(:ring_account_device).new(:name => 'foo/bar') - }.to raise_error(Puppet::Error, /should contain address:port\/device/) + Puppet::Type.type(:ring_container_device).new(:name => '192.168.1.256:80/a') + }.to raise_error(Puppet::ResourceError, /invalid address/) end it 'should fail if the name does not contain a "/"' do expect { - Puppet::Type.type(:ring_account_device).new(:name => 'foo:80') + Puppet::Type.type(:ring_container_device).new(:name => 'foo:80') }.to raise_error(Puppet::Error, /should contain a device/) end end diff --git a/swift/spec/unit/puppet/type/ring_object_device_spec.rb b/swift/spec/unit/puppet/type/ring_object_device_spec.rb index 05861bb17..4897f78cb 100644 --- a/swift/spec/unit/puppet/type/ring_object_device_spec.rb +++ b/swift/spec/unit/puppet/type/ring_object_device_spec.rb @@ -1,15 +1,14 @@ require 'puppet' describe Puppet::Type.type(:ring_object_device) do - - it 'should fail if the name has no ":"' do + it 'should fail if the name does not contain valid ipaddress' do expect { - Puppet::Type.type(:ring_account_device).new(:name => 'foo/bar') - }.to raise_error(Puppet::Error, /should contain address:port\/device/) + Puppet::Type.type(:ring_object_device).new(:name => '192.168.1.256:80/a') + }.to raise_error(Puppet::ResourceError, /invalid address/) end it 'should fail if the name does not contain a "/"' do expect { - Puppet::Type.type(:ring_account_device).new(:name => 'foo:80') + Puppet::Type.type(:ring_object_device).new(:name => 'foo:80') }.to raise_error(Puppet::Error, /should contain a device/) end end diff --git a/swift/templates/proxy-server.conf.erb b/swift/templates/proxy-server.conf.erb index 1a7987387..f6db44d09 100644 --- a/swift/templates/proxy-server.conf.erb +++ b/swift/templates/proxy-server.conf.erb @@ -33,6 +33,7 @@ log_handoffs = <%= @log_handoffs %> allow_account_management = <%= @allow_account_management %> account_autocreate = <%= @account_autocreate %> <% if @read_affinity -%> +sorting_method = affinity read_affinity = <%= @read_affinity -%> <% end %> <% if @write_affinity -%> diff --git a/tempest/LICENSE b/tempest/LICENSE new file mode 100644 index 000000000..88a11a0e7 --- /dev/null +++ b/tempest/LICENSE @@ -0,0 +1,13 @@ +Copyright 2012 OpenStack Foundation + +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/tempest/spec/classes/tempest_spec.rb b/tempest/spec/classes/tempest_spec.rb index 9c6eba208..478c3f431 100644 --- a/tempest/spec/classes/tempest_spec.rb +++ b/tempest/spec/classes/tempest_spec.rb @@ -103,11 +103,21 @@ :image_name => 'image name', :image_name_alt => 'image name alt', :public_network_name => 'network name', - :neutron_available => true } + :neutron_available => true, + :install_from_source => true + } end describe "should install tempest" do it 'installs packages' do + + is_expected.to contain_package('git') + is_expected.to contain_package('python-setuptools') + + platform_params[:dev_packages].each do |package| + is_expected.to contain_package("#{package}") + end + is_expected.to contain_class('tempest::params') is_expected.to contain_exec('install-pip').with( @@ -176,6 +186,7 @@ is_expected.to contain_tempest_config('service_available/nova').with(:value => true) is_expected.to contain_tempest_config('service_available/swift').with(:value => false) is_expected.to contain_tempest_config('whitebox/db_uri').with(:value => nil) + is_expected.to contain_tempest_config('cli/cli_dir').with(:value => nil) end it 'set glance id' do @@ -208,7 +219,17 @@ context 'on Debian platforms' do let :facts do - { :osfamily => 'Debian' } + { :osfamily => 'Debian' } + end + + let :platform_params do + { :dev_packages => ['python-dev', + 'libxslt1-dev', + 'libxml2-dev', + 'libssl-dev', + 'libffi-dev', + 'patch', + 'gcc' ] } end it_behaves_like 'tempest' @@ -219,6 +240,16 @@ { :osfamily => 'RedHat' } end + let :platform_params do + { :dev_packages => ['python-devel', + 'libxslt-devel', + 'libxml2-devel', + 'openssl-devel', + 'libffi-devel', + 'patch', + 'gcc' ] } + end + it_behaves_like 'tempest' end diff --git a/tempest/spec/spec_helper.rb b/tempest/spec/spec_helper.rb index 6d13239e4..2d7f9eea4 100644 --- a/tempest/spec/spec_helper.rb +++ b/tempest/spec/spec_helper.rb @@ -4,3 +4,5 @@ RSpec.configure do |c| c.alias_it_should_behave_like_to :it_raises, 'raises' end + +at_exit { RSpec::Puppet::Coverage.report! } diff --git a/tripleo/manifests/loadbalancer.pp b/tripleo/manifests/loadbalancer.pp index 1d605076f..6601cf92a 100644 --- a/tripleo/manifests/loadbalancer.pp +++ b/tripleo/manifests/loadbalancer.pp @@ -58,6 +58,10 @@ # FQDN of the Galera master node # Defaults to undef # +# [*galera_master_ip*] +# IP of the Galera master node +# Defaults to undef +# # [*keystone_admin*] # (optional) Enable or not Keystone Admin API binding # Defaults to false @@ -130,6 +134,10 @@ # (optional) Enable or not RabbitMQ binding # Defaults to false # +# [*redis*] +# (optional) Enable or not Redis binding +# Defaults to false +# class tripleo::loadbalancer ( $controller_virtual_ip, $control_virtual_interface, @@ -139,6 +147,7 @@ $controller_hosts = undef, $controller_hosts_names = undef, $galera_master_hostname = undef, + $galera_master_ip = undef, $keystone_admin = false, $keystone_public = false, $neutron = false, @@ -157,6 +166,7 @@ $horizon = false, $mysql = false, $rabbitmq = false, + $redis = false, ) { if !$controller_host and !$controller_hosts { @@ -540,17 +550,23 @@ }, collect_exported => false, } - if downcase($galera_master_hostname) == $::hostname or !$galera_master_hostname { - $options_real = ['check', 'inter 2000', 'rise 2', 'fall 5'] - } else { - $options_real = ['check', 'inter 2000', 'rise 2', 'fall 5', 'backup'] - } + haproxy::balancermember { 'mysql': listening_service => 'mysql', ports => '3306', - ipaddresses => $controller_hosts_real, - server_names => $controller_hosts_names_real, - options => $options_real, + ipaddresses => $galera_master_ip, + server_names => $galera_master_hostname, + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + + $controller_hosts_without_galera_master = delete($controller_hosts_real, $galera_master_ip) + $controller_hosts_names_without_galera_master = delete($controller_hosts_names_real, downcase($galera_master_hostname)) + haproxy::balancermember { 'mysql-backup': + listening_service => 'mysql', + ports => '3306', + ipaddresses => $controller_hosts_without_galera_master, + server_names => $controller_hosts_names_without_galera_master, + options => ['check', 'inter 2000', 'rise 2', 'fall 5', 'backup'], } } @@ -572,4 +588,26 @@ } } + if $redis { + haproxy::listen { 'redis': + ipaddress => [$controller_virtual_ip], + ports => 6379, + options => { + 'timeout' => [ 'client 0', 'server 0' ], + 'mode' => 'tcp', + 'balance' => 'first', + 'option' => ['tcp-check',], + 'tcp-check' => ['send info\ replication\r\n','expect string role:master'], + }, + collect_exported => false, + } + haproxy::balancermember { 'redis': + listening_service => 'redis', + ports => '6379', + ipaddresses => $controller_hosts_real, + server_names => $controller_hosts_names_real, + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + } diff --git a/tripleo/manifests/redis_notification.pp b/tripleo/manifests/redis_notification.pp new file mode 100644 index 000000000..ad059a08f --- /dev/null +++ b/tripleo/manifests/redis_notification.pp @@ -0,0 +1,38 @@ +# Copyright 2015 Red Hat, Inc. +# All Rights Reserved. +# +# 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. +# +# == Class: tripleo::redis_notification +# +# Configure the Redis notification script that talks to HAProxy +# +# === Parameters: +# +# [*haproxy_monitor_ip*] +# (String) IP address on which HAProxy is listening on +# Defaults to 127.0.0.1 +# +class tripleo::redis_notification ( + $haproxy_monitor_ip = '127.0.0.1', +) { + + file { '/usr/local/bin/redis-notifications.sh' : + ensure => file, + content => template('tripleo/redis/redis-notifications.sh.erb'), + owner => 'root', + group => 'root', + mode => '0755', + } + +} diff --git a/tripleo/templates/redis/redis-notifications.sh.erb b/tripleo/templates/redis/redis-notifications.sh.erb new file mode 100644 index 000000000..aa368e9fa --- /dev/null +++ b/tripleo/templates/redis/redis-notifications.sh.erb @@ -0,0 +1,30 @@ +#!/bin/bash +HAPROXY="<%= @haproxy_monitor_ip %>:1993" +CMD="$1" +ARGS="$2" +ARG1=`echo $ARGS | awk '{print $1}'` + + +call_curl () { + DATA=`echo "s=$1&action=$2&b=%234" | sed -e s/:/%3A/` + curl --silent -o /dev/null $HAPROXY --data "$DATA" + echo curl $HAPROXY --data "$DATA" + return 0 +} + + +[ "$CMD" = "+odown" ] && [ "$ARG1" = "master" ] && \ + call_curl `echo $ARGS | awk '{print $2 ":" $3 ":" $4}'` 'disable' + +[ "$CMD" = "+sdown" ] && [ "$ARG1" = "slave" ] && \ + call_curl `echo $ARGS | awk '{print $6 ":" $3 ":" $4}'` 'disable' + +[ "$CMD" = "+switch-master" ] && \ + call_curl `echo $ARGS | awk '{print $1 ":" $4 ":" $5}'` 'enable' && + call_curl `echo $ARGS | awk '{print $1 ":" $2 ":" $3}'` 'disable' + +[ "$CMD" = "-odown" ] && [ "$ARG1" = "master" ] && \ + call_curl `echo $ARGS | awk '{print $2 ":" $3 ":" $4}'` 'enable' + +# without exit code, sentinel thinks the script is still running and locks any further execution +exit 0 diff --git a/vcsrepo/README.markdown b/vcsrepo/README.markdown index 9671fc592..2433d99ff 100644 --- a/vcsrepo/README.markdown +++ b/vcsrepo/README.markdown @@ -49,7 +49,7 @@ Also, this module, like Puppet generally, will not create parent directories for To get started with the vcsrepo module, you must simply define the type `vcsrepo` with a path to your repository and the [type of VCS](#Usage) you're using in `provider` (in the below example, Git). - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, } @@ -75,14 +75,14 @@ The vcsrepo module works with the following VCSs: To create a blank repository suitable for use as a central repository, define `vcsrepo` without `source` or `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, } If you're defining `vcsrepo` for a central or official repository, you may want to make it a bare repository. You do this by setting `ensure` to 'bare' rather than 'present'. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => bare, provider => git, } @@ -91,17 +91,17 @@ If you're defining `vcsrepo` for a central or official repository, you may want To get the current HEAD on the master branch, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, - source => "git://example.com/repo.git", + source => 'git://example.com/repo.git', } To get a specific revision or branch (can be a commit SHA, tag, or branch name), **SHA** - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, source => 'git://example.com/repo.git', @@ -110,7 +110,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name), **Tag** - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, source => 'git://example.com/repo.git', @@ -119,7 +119,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name), **Branch name** - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, source => 'git://example.com/repo.git', @@ -128,7 +128,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name), To check out a branch as a specific user, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, source => 'git://example.com/repo.git', @@ -138,7 +138,7 @@ To check out a branch as a specific user, To keep the repository at the latest revision (**WARNING:** this will always overwrite local changes to the repository), - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => latest, provider => git, source => 'git://example.com/repo.git', @@ -147,7 +147,7 @@ To keep the repository at the latest revision (**WARNING:** this will always ove To clone the repository but skip initialiazing submodules, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => latest, provider => git, source => 'git://example.com/repo.git', @@ -157,12 +157,12 @@ To clone the repository but skip initialiazing submodules, ##### Using multiple remotes with a repository Instead of specifying a single string in the 'source' property, you can specify a hash with multiple name => URL mappings, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => git, source => { - "origin" => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git", - "other_remote" => "https://github.com/other_user/puppetlabs-vcsrepo.git" + origin => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git', + other_remote => 'https://github.com/other_user/puppetlabs-vcsrepo.git' }, } @@ -187,7 +187,7 @@ For more examples using Git, see `examples/git/`. To create a blank repository suitable for use as a central repository, define `vcsrepo` without `source` or `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => bzr, } @@ -196,7 +196,7 @@ define `vcsrepo` without `source` or `revision`. Provide the `source` location to branch from an existing repository. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => bzr, source => 'lp:myproj', @@ -205,7 +205,7 @@ Provide the `source` location to branch from an existing repository. For a specific revision, use `revision` with a valid revisionspec (see `bzr help revisionspec` for more information on formatting a revision). - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => bzr, source => 'lp:myproj', @@ -228,7 +228,7 @@ For more examples using Bazaar, see `examples/bzr/`. To create a blank repository suitable for use as a central repository, define `vcsrepo` without `source` or `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => cvs, } @@ -237,39 +237,39 @@ define `vcsrepo` without `source` or `revision`. To get the current mainline, - vcsrepo { "/path/to/workspace": + vcsrepo { '/path/to/workspace': ensure => present, provider => cvs, - source => ":pserver:anonymous@example.com:/sources/myproj", + source => ':pserver:anonymous@example.com:/sources/myproj', } To get a specific module on the current mainline, - vcsrepo {"/vagrant/lockss-daemon-source": + vcsrepo {'/vagrant/lockss-daemon-source': ensure => present, provider => cvs, - source => ":pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss", - module => "lockss-daemon", + source => ':pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss', + module => 'lockss-daemon', } You can use the `compression` parameter to set the GZIP compression levels for your repository history. - vcsrepo { "/path/to/workspace": + vcsrepo { '/path/to/workspace': ensure => present, provider => cvs, compression => 3, - source => ":pserver:anonymous@example.com:/sources/myproj", + source => ':pserver:anonymous@example.com:/sources/myproj', } For a specific tag, use `revision`. - vcsrepo { "/path/to/workspace": + vcsrepo { '/path/to/workspace': ensure => present, provider => cvs, compression => 3, - source => ":pserver:anonymous@example.com:/sources/myproj", - revision => "SOMETAG", + source => ':pserver:anonymous@example.com:/sources/myproj', + revision => 'SOMETAG', } #####Sources that use SSH @@ -287,7 +287,7 @@ For for more examples using CVS, see `examples/cvs/`. To create a blank repository suitable for use as a central repository, define `vcsrepo` without `source` or `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, } @@ -296,51 +296,51 @@ define `vcsrepo` without `source` or `revision`. To get the default branch tip, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, - source => "http://hg.example.com/myrepo", + source => 'http://hg.example.com/myrepo', } For a specific changeset, use `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, - source => "http://hg.example.com/myrepo", + source => 'http://hg.example.com/myrepo', revision => '21ea4598c962', } You can also set `revision` to a tag. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, - source => "http://hg.example.com/myrepo", + source => 'http://hg.example.com/myrepo', revision => '1.1.2', } To check out as a specific user, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, - source => "http://hg.example.com/myrepo", + source => 'http://hg.example.com/myrepo', user => 'user', } To specify an SSH identity key, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => hg, - source => "ssh://hg@hg.example.com/myrepo", - identity => "/home/user/.ssh/id_dsa, + source => 'ssh://hg@hg.example.com/myrepo', + identity => '/home/user/.ssh/id_dsa', } To specify a username and password for HTTP Basic authentication, - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => latest, provider => hg, source => 'http://hg.example.com/myrepo', @@ -364,7 +364,7 @@ To create an empty Workspace, define a `vcsrepo` without a `source` or `revision Environment variables P4PORT, P4USER, etc... are used to define the Perforce server connection settings. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => p4 } @@ -378,7 +378,7 @@ A Perforce configuration file can be used by setting the `P4CONFIG` environment defining `p4config`. If a configuration is defined, then the environment variable for `P4CLIENT` is replaced. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => p4, p4config => '.p4config' @@ -388,7 +388,7 @@ defining `p4config`. If a configuration is defined, then the environment variab To sync a depot path to head, ensure `latest`: - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => latest, provider => p4, source => '//depot/branch/...' @@ -396,7 +396,7 @@ To sync a depot path to head, ensure `latest`: For a specific changelist, ensure `present` and specify a `revision`: - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => p4, source => '//depot/branch/...', @@ -405,7 +405,7 @@ For a specific changelist, ensure `present` and specify a `revision`: You can also set `revision` to a label: - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => p4, source => '//depot/branch/...', @@ -428,7 +428,7 @@ For examples you can run, see `examples/p4/` To create a blank repository suitable for use as a central repository, define `vcsrepo` without `source` or `revision`. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => svn, } @@ -437,18 +437,18 @@ define `vcsrepo` without `source` or `revision`. Provide a `source` pointing to the branch/tag you want to check out from a repository. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => svn, - source => "svn://svnrepo/hello/branches/foo", + source => 'svn://svnrepo/hello/branches/foo', } You can also provide a specific revision. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => svn, - source => "svn://svnrepo/hello/branches/foo", + source => 'svn://svnrepo/hello/branches/foo', revision => '1234', } @@ -456,11 +456,11 @@ You can also provide a specific revision. To use a specific configuration directory, provide a `configuration` parameter which should be a directory path on the local system where your svn configuration files are. Typically, it is '/path/to/.subversion'. - vcsrepo { "/path/to/repo": + vcsrepo { '/path/to/repo': ensure => present, provider => svn, - source => "svn://svnrepo/hello/branches/foo", - configuration => "/path/to/.subversion", + source => 'svn://svnrepo/hello/branches/foo', + configuration => '/path/to/.subversion', } #####Sources that use SSH diff --git a/vswitch/Gemfile b/vswitch/Gemfile index f3182fde2..b0b2d45ff 100644 --- a/vswitch/Gemfile +++ b/vswitch/Gemfile @@ -2,10 +2,20 @@ source 'https://rubygems.org' group :development, :test do gem 'puppetlabs_spec_helper', :require => false - gem 'puppet-lint', '~> 0.3.2' - gem 'rspec-puppet', '~> 1.0.1' - gem 'rake', '10.1.1' - gem 'rspec', '< 2.99' + gem 'rspec-puppet', '~> 2.0.0', :require => false + + gem 'metadata-json-lint' + gem 'puppet-lint-param-docs' + gem 'puppet-lint-absolute_classname-check' + gem 'puppet-lint-absolute_template_path' + gem 'puppet-lint-trailing_newline-check' + + # Puppet 4.x related lint checks + gem 'puppet-lint-unquoted_string-check' + gem 'puppet-lint-leading_zero-check' + gem 'puppet-lint-variable_contains_upcase' + gem 'puppet-lint-numericvariable' + gem 'json' gem 'webmock' end diff --git a/vswitch/manifests/init.pp b/vswitch/manifests/init.pp index 196e655b8..d0d51cab8 100644 --- a/vswitch/manifests/init.pp +++ b/vswitch/manifests/init.pp @@ -27,6 +27,6 @@ class vswitch ( $provider = $vswitch::params::provider ) { - $cls = "vswitch::${provider}" + $cls = "::vswitch::${provider}" include $cls } diff --git a/vswitch/manifests/ovs.pp b/vswitch/manifests/ovs.pp index 9ce892ccf..e04c6226f 100644 --- a/vswitch/manifests/ovs.pp +++ b/vswitch/manifests/ovs.pp @@ -1,10 +1,14 @@ # vswitch: open-vswitch # +# [*package_ensure*] +# (Optional) State of the openvswitch package +# Defaults to 'present'. +# class vswitch::ovs( $package_ensure = 'present' ) { - include 'vswitch::params' + include ::vswitch::params case $::osfamily { 'Debian': { @@ -21,27 +25,27 @@ $ovs_status = '/etc/init.d/openvswitch-switch status | fgrep "is running"' } } - service {'openvswitch': - ensure => true, - enable => true, - name => $::vswitch::params::ovs_service_name, - hasstatus => false, # the supplied command returns true even if it's not running + service { 'openvswitch': + ensure => true, + enable => true, + name => $::vswitch::params::ovs_service_name, + hasstatus => false, # the supplied command returns true even if it's not running # Not perfect - should spot if either service is not running - but it'll do - status => $ovs_status + status => $ovs_status, } exec { 'rebuild-ovsmod': command => '/usr/sbin/dpkg-reconfigure openvswitch-datapath-dkms > /tmp/reconf-log', creates => "/lib/modules/${::kernelrelease}/updates/dkms/openvswitch_mod.ko", require => [Package['openvswitch-datapath-dkms', $kernelheaders_pkg]], before => Package['openvswitch-switch'], - refreshonly => true + refreshonly => true, } } 'Redhat': { - service {'openvswitch': - ensure => true, - enable => true, - name => $::vswitch::params::ovs_service_name, + service { 'openvswitch': + ensure => true, + enable => true, + name => $::vswitch::params::ovs_service_name, } } default: { @@ -50,8 +54,8 @@ } package { $::vswitch::params::ovs_package_name: - ensure => $package_ensure, - before => Service['openvswitch'], + ensure => $package_ensure, + before => Service['openvswitch'], } Service['openvswitch'] -> Vs_port<||> diff --git a/vswitch/metadata.json b/vswitch/metadata.json index 69c3b704e..d16d076dd 100644 --- a/vswitch/metadata.json +++ b/vswitch/metadata.json @@ -3,7 +3,7 @@ "version": "1.0.0", "source": "https://github.com/stackforge/puppet-vswitch", "author": "Endre Karlson, Dan Bode and StackForge Contributors", - "license": "Apache License 2.0", + "license": "Apache-2.0", "source": "git://github.com/stackforge/puppet-vswitch.git", "project_page": "https://launchpad.net/puppet-vswitch", "issues_url": "https://bugs.launchpad.net/puppet-vswitch", diff --git a/vswitch/spec/classes/vswitch_ovs_spec.rb b/vswitch/spec/classes/vswitch_ovs_spec.rb index de7e14651..c3b0d2928 100644 --- a/vswitch/spec/classes/vswitch_ovs_spec.rb +++ b/vswitch/spec/classes/vswitch_ovs_spec.rb @@ -10,13 +10,13 @@ it 'should contain the correct package and service' do - should contain_service('openvswitch').with( + is_expected.to contain_service('openvswitch').with( :ensure => true, :enable => true, :name => 'openvswitch' ) - should contain_package('openvswitch').with( + is_expected.to contain_package('openvswitch').with( :name => 'openvswitch', :ensure => 'present', :before => 'Service[openvswitch]' diff --git a/xinetd/.travis.yml b/xinetd/.travis.yml index e69e7f5be..b523f5ba1 100644 --- a/xinetd/.travis.yml +++ b/xinetd/.travis.yml @@ -1,6 +1,6 @@ --- language: ruby -bundler_args: --without development +bundler_args: --without system_tests script: "bundle exec rake spec SPEC_OPTS='--format documentation'" rvm: - 1.8.7 diff --git a/xinetd/Gemfile b/xinetd/Gemfile index 6d274a4b2..3cdc63c34 100644 --- a/xinetd/Gemfile +++ b/xinetd/Gemfile @@ -1,10 +1,13 @@ source 'https://rubygems.org' -group :development, :test do +group :development, :unit_test do gem 'rake', :require => false gem 'rspec-puppet', '~> 1.0', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', :require => false +end + +group :system_tests do gem 'serverspec', :require => false gem 'rspec-system', :require => false gem 'rspec-system-puppet', :require => false diff --git a/xinetd/README.md b/xinetd/README.md index ada4d0e9d..21dc2ab0d 100644 --- a/xinetd/README.md +++ b/xinetd/README.md @@ -24,6 +24,31 @@ package names and service needs. * `service_hasrestart` * `service_hasstatus` +Additionally, all the global defaults in the main xinetd.conf can be set. By +default they are *not* set, allowing the internal xinetd defaults to be used: +(see `man xinetd.conf` for full descriptions) + + * `enabled` - Takes a list of service ID's to enable. + * `disabled` - Takes a list of service ID's to disable. + * `log_type` - Determines where the service log output is sent. + * `log_on_failure` - Determines what information is logged when a server cannot be started. + * `log_on_success` - Determines what information is logged when a server is started and when that server exits. + * `no_access` - Determines the remote hosts to which the particular service is unavailable. + * `only_from` - Determines the remote hosts to which the particular service is available. + * `max_load` - Takes a floating point value as the load at which the service will stop accepting connections. + * `instances` - Determines the number of servers that can be simultaneously active for a service (the default is no limit). + * `per_source` - This specifies the maximum instances of this service per source IP address. + * `bind` - Allows a service to be bound to a specific interface on the machine. + * `mdns` - On systems that support mdns registration of services (currently only Mac OS X), this will enable or disable registration of the service. + * `v6only` - Set to yes to use IPv6 only. + * `passenv` - The value of this attribute is a list of environment variables from xinetd's environment that will be passed to the server. + * `env` - The value of this attribute is a list of environment variables that will be added to the environment before starting a server. + * `groups` - If the groups attribute is set to "yes", then the server is executed with access to the groups that the server's effective UID has access to. + * `umask` - Sets the inherited umask for the service. + * `banner` - Takes the name of a file to be splatted at the remote host when a connection to that service is established. + * `banner_fail` - Takes the name of a file to be splatted at the remote host when a connection to that service is denied. + * `banner_success` - Takes the name of a file to be splatted at the remote host when a connection to that service is granted. + ## Definition: xinetd::service Sets up a xinetd service. All parameters match up with xinetd.conf(5) man diff --git a/xinetd/Rakefile b/xinetd/Rakefile index bb60173e5..4b927db0b 100644 --- a/xinetd/Rakefile +++ b/xinetd/Rakefile @@ -1,2 +1,5 @@ require 'puppetlabs_spec_helper/rake_tasks' -require 'rspec-system/rake_task' +begin + require 'rspec-system/rake_task' +rescue LoadError +end diff --git a/xinetd/manifests/init.pp b/xinetd/manifests/init.pp index 226793da6..aa0b4923e 100644 --- a/xinetd/manifests/init.pp +++ b/xinetd/manifests/init.pp @@ -19,7 +19,27 @@ $service_status = $xinetd::params::service_status, $service_hasrestart = $xinetd::params::service_hasrestart, $service_hasstatus = $xinetd::params::service_hasstatus, - $purge_confdir = false, + $enabled = undef, + $disabled = undef, + $log_type = undef, + $log_on_failure = undef, + $log_on_success = undef, + $no_access = undef, + $only_from = undef, + $max_load = undef, + $instances = undef, + $per_source = undef, + $bind = undef, + $mdns = undef, + $v6only = undef, + $env = undef, + $passenv = undef, + $groups = undef, + $umask = undef, + $banner = undef, + $banner_fail = undef, + $banner_success = undef, + $purge_confdir = undef, ) inherits xinetd::params { File { diff --git a/xinetd/manifests/service.pp b/xinetd/manifests/service.pp index 3a0371fc3..43d122d71 100644 --- a/xinetd/manifests/service.pp +++ b/xinetd/manifests/service.pp @@ -89,7 +89,8 @@ $access_times = undef, $log_type = undef, $bind = undef, - $nice = undef + $nice = undef, + $env = undef, ) { include xinetd diff --git a/xinetd/spec/classes/xinetd_init_spec.rb b/xinetd/spec/classes/xinetd_init_spec.rb index 39b471bbb..7728cd544 100644 --- a/xinetd/spec/classes/xinetd_init_spec.rb +++ b/xinetd/spec/classes/xinetd_init_spec.rb @@ -2,22 +2,109 @@ describe 'xinetd' do - let :facts do - { :osfamily => 'Debian' } + context 'When using default values' do + let :facts do + { :osfamily => 'Debian' } + end + it { + should contain_package('xinetd') + should contain_file('/etc/xinetd.conf') + should contain_service('xinetd') + } + it { + # Ensure that the config file allows xinetd to use its own defaults + should contain_file('/etc/xinetd.conf').without_content(/enabled *=/) + should contain_file('/etc/xinetd.conf').without_content(/disabled *=/) + should contain_file('/etc/xinetd.conf').without_content(/log_type *=/) + should contain_file('/etc/xinetd.conf').without_content(/log_on_failure *=/) + should contain_file('/etc/xinetd.conf').without_content(/log_on_success *=/) + should contain_file('/etc/xinetd.conf').without_content(/no_access *=/) + should contain_file('/etc/xinetd.conf').without_content(/only_from *=/) + should contain_file('/etc/xinetd.conf').without_content(/max_load *=/) + should contain_file('/etc/xinetd.conf').without_content(/instances *=/) + should contain_file('/etc/xinetd.conf').without_content(/per_source *=/) + should contain_file('/etc/xinetd.conf').without_content(/bind *=/) + should contain_file('/etc/xinetd.conf').without_content(/mdns *=/) + should contain_file('/etc/xinetd.conf').without_content(/v6only *=/) + should contain_file('/etc/xinetd.conf').without_content(/passenv *=/) + should contain_file('/etc/xinetd.conf').without_content(/env *=/) + should contain_file('/etc/xinetd.conf').without_content(/groups *=/) + should contain_file('/etc/xinetd.conf').without_content(/umask *=/) + should contain_file('/etc/xinetd.conf').without_content(/banner *=/) + should contain_file('/etc/xinetd.conf').without_content(/banner_fail *=/) + should contain_file('/etc/xinetd.conf').without_content(/banner_success *=/) + } end - describe 'with defaults' do + context 'When overriding the default vaules' do + let :facts do + { :osfamily => 'Debian' } + end + let :params do + { :enabled => 'tftp nrpe', + :disabled => 'time echo', + :log_type => 'SYSLOG daemon info', + :log_on_failure => 'HOST', + :log_on_success => 'PID HOST DURATION EXIT', + :no_access => '128.138.209.10', + :only_from => '127.0.0.1', + :max_load => '2', + :instances => '50', + :per_source => '50', + :bind => '0.0.0.0', + :mdns => 'yes', + :v6only => 'no', + :env => 'foo=bar', + :passenv => 'yes', + :groups => 'yes', + :umask => '002', + :banner => '/etc/banner', + :banner_fail => '/etc/banner.fail', + :banner_success => '/etc/banner.good', + } + end + it { + # Ensure that the config file allows xinetd to use its own defaults + should contain_file('/etc/xinetd.conf').with_content(/enabled *= tftp nrpe/) + should contain_file('/etc/xinetd.conf').with_content(/disabled *= time echo/) + should contain_file('/etc/xinetd.conf').with_content(/log_type *= SYSLOG daemon info/) + should contain_file('/etc/xinetd.conf').with_content(/log_on_failure *= HOST/) + should contain_file('/etc/xinetd.conf').with_content(/log_on_success *= PID HOST DURATION EXIT/) + should contain_file('/etc/xinetd.conf').with_content(/no_access *= 128.138.209.10/) + should contain_file('/etc/xinetd.conf').with_content(/only_from *= 127.0.0.1/) + should contain_file('/etc/xinetd.conf').with_content(/max_load *= 2/) + should contain_file('/etc/xinetd.conf').with_content(/instances *= 50/) + should contain_file('/etc/xinetd.conf').with_content(/per_source *= 50/) + should contain_file('/etc/xinetd.conf').with_content(/bind *= 0.0.0.0/) + should contain_file('/etc/xinetd.conf').with_content(/mdns *= yes/) + should contain_file('/etc/xinetd.conf').with_content(/v6only *= no/) + should contain_file('/etc/xinetd.conf').with_content(/env *= foo=bar/) + should contain_file('/etc/xinetd.conf').with_content(/passenv *= yes/) + should contain_file('/etc/xinetd.conf').with_content(/passenv *= yes/) + should contain_file('/etc/xinetd.conf').with_content(/groups *= yes/) + should contain_file('/etc/xinetd.conf').with_content(/umask *= 002/) + should contain_file('/etc/xinetd.conf').with_content(/banner *= \/etc\/banner/) + should contain_file('/etc/xinetd.conf').with_content(/banner_fail *= \/etc\/banner\.fail/) + should contain_file('/etc/xinetd.conf').with_content(/banner_success *= \/etc\/banner\.good/) + } + end + + context 'with defaults' do + let :facts do + { :osfamily => 'Debian' } + end it { should contain_package('xinetd') should contain_file('/etc/xinetd.conf') should contain_file('/etc/xinetd.d').with_ensure('directory') - should contain_file('/etc/xinetd.d').with_recurse(false) - should contain_file('/etc/xinetd.d').with_purge(false) should contain_service('xinetd') } end - describe 'with managed confdir' do + context 'with managed confdir' do + let :facts do + { :osfamily => 'Debian' } + end let :params do { :purge_confdir => true } end diff --git a/xinetd/templates/service.erb b/xinetd/templates/service.erb index a35f15471..cf44c3683 100644 --- a/xinetd/templates/service.erb +++ b/xinetd/templates/service.erb @@ -54,4 +54,7 @@ service <%= @service_name %> <% if @nice -%> nice = <%= @nice %> <% end -%> +<% if @env -%> + env = <%= @env %> +<% end -%> } diff --git a/xinetd/templates/xinetd.conf.erb b/xinetd/templates/xinetd.conf.erb index 3a0842966..e9412577c 100644 --- a/xinetd/templates/xinetd.conf.erb +++ b/xinetd/templates/xinetd.conf.erb @@ -11,41 +11,79 @@ defaults { # The next two items are intended to be a quick access place to # temporarily enable or disable services. -# -# enabled = -# disabled = +<% if @enabled -%> + enabled = <%= @enabled -%> +<% end %> +<% if @disabled -%> + disabled = <%= @disabled -%> +<% end %> # Define general logging characteristics. - log_type = SYSLOG daemon info - log_on_failure = HOST - log_on_success = PID HOST DURATION EXIT +<% if @log_type -%> + log_type = <%= @log_type -%> +<% end %> +<% if @log_on_failure -%> + log_on_failure = <%= @log_on_failure -%> +<% end %> +<% if @log_on_success -%> + log_on_success = <%= @log_on_success -%> +<% end %> # Define access restriction defaults -# -# no_access = -# only_from = -# max_load = 0 - cps = 50 10 - instances = 50 - per_source = 10 +<% if @no_access -%> + no_access = <%= @no_access -%> +<% end %> +<% if @only_from -%> + only_from = <%= @only_from -%> +<% end %> +<% if @max_load -%> + max_load = <%= @max_load -%> +<% end %> +<% if @cps -%> + cps = <%= @cps -%> +<% end %> +<% if @instances -%> + instances = <%= @instances -%> +<% end %> +<% if @per_source -%> + per_source = <%= @per_source -%> +<% end %> # Address and networking defaults -# -# bind = -# mdns = yes - v6only = no +<% if @bind -%> + bind = <%= @bind -%> +<% end %> +<% if @mdns -%> + mdns = <%= @mdns -%> +<% end %> +<% if @v6only -%> + v6only = <%= @v6only -%> +<% end %> # setup environmental attributes -# -# passenv = - groups = yes - umask = 002 +<% if @env -%> + env = <%= @env -%> +<% end %> +<% if @passenv -%> + passenv = <%= @passenv -%> +<% end %> +<% if @groups -%> + groups = <%= @groups -%> +<% end %> +<% if @umask -%> + umask = <%= @umask -%> +<% end %> # Generally, banners are not used. This sets up their global defaults -# -# banner = -# banner_fail = -# banner_success = +<% if @banner -%> + banner = <%= @banner -%> +<% end %> +<% if @banner_fail -%> + banner_fail = <%= @banner_fail -%> +<% end %> +<% if @banner_success -%> + banner_success = <%= @banner_success -%> +<% end %> } includedir <%= @confdir %>