From 3e0c8628531f19b5e3426bdd2b131b017e1372cd Mon Sep 17 00:00:00 2001 From: Gael Chamoulaud Date: Thu, 19 Feb 2015 14:04:09 +0100 Subject: [PATCH] Update haproxy to cf5c18ca25b8bb201e2dc61af5a938fe5b05ba70 cf5c18ca25b8bb201e2dc61af5a938fe5b05ba70 Merge pull request #156 from mhaskel/peer_fix 973a70908df1694f7f852e708639bdcf1f67cb4d Missing ensure for peer dd2bbb2d14002759b45a03185d737f20cc9d9748 Merge pull request #148 from jewjitsu/addfreebsd 0ab19096cf9bd866a3446bf34945ea3892e8448c Merge pull request #125 from cernops/peers_feature fd72f441766cfb5f9bfc8a5a4703e860720028b8 add support for freebsd 4f0009dcab7ab52ae985910d1986634136e8c6c4 Merge pull request #154 from antaflos/bind_parameter_flexibility 1041fba08b9dc0b6045448c592b29a8431214ab1 Make `bind` parameter processing more flexible 047a542cf2ff5066c79bfc83b7c51fc7ac99468d Merge pull request #153 from cmurphy/rspec 32af63dc63d0ca810d6e412c16007f201b0baf2c Pin rspec gems b59bd15fca6e69c9555ba9fb73961af51ca4732c Merge pull request #151 from mhaskel/future_parser_fix 87ad80efd4a5cc73c525001d16cbf840e3de7ae2 future parser fix de12d2979545465d145b9b401b28e2e3dd0b3efd Merge pull request #120 from eric-iweb/noport d358462056ab29248ecb40757e019aa59b148b67 Merge pull request #137 from gildub/bug+params+osfamily 3b2ca7f05086f70c3ddd8b2d0bcb487dedd0926d Merge pull request #145 from t0mmyt/namespace_cleanup efc48ec7b152e77f4f31d9863a5f758776191ab9 Merge pull request #142 from matthewfischer/master 89083c737eb81c74e54e7b81d2ffa86cb8b8188c Merge pull request #150 from tphoney/adding_default_nodeset 777502248e4a21d861478e03c085e626478d051b adding a default option into nodesets 2f309c7ee3096543e13cc817803bd164c91c6677 Merge pull request #147 from tphoney/modules_1497 d68719f5528e6bbfe3530bb7f192b4dec29b6fea modules-1497 listen cannot use bind and ip address 21cc9532f5699a774d04bb2d9c7434588598dc43 Fix spec's to reflect changes 31a15dea809016bdc35f2666ade9919cf123a4ed Set ipaddress default value to undef 34b5d451cffeb1c94bb3546d7805cbebcd062c7c Added peer functionality e90c5fc085ba7d98b3b4850b93e3722367524631 Corrected namespaces on variables decd2de85ad4ec61519c482ec0f03e543d0522dc Merge pull request #144 from petems/MODULES-1619-add_haproxy_version_fact de4a194c0109633ce339f6b54bdd3f964a77e00e (MODULES-1619) Stub exec to fix older facts c607a6ae4fb9b24399e270ccf6caa7f545b43dc0 (MODULES-1619) Adds spec for when haproxy missing 894f8d4cd625215f4e17c22fca897e819f7e61f8 (MODULES-1619) Only run when haproxy present deadaa9d51fcf3bcd28214df425ef96ff9a993ef (MODULES-1619) Add version fact for haproxy fd307ace2580c825848030e51c9010d2d2699ac7 Fix the TOC in the README f74d7490b067bf39577711b79e7e06b1b905414e Merge pull request #141 from cmurphy/master 0d98250e37b3821e8765cd9a05f2fd9e792118d5 Sync with modulesync 1d830522ad0671e9fa3514442915e64ed6014e50 Merge pull request #134 from jbondpdx/master 5e0479ea0700d55f4f02afcf61bbbf3165e70fd2 Fixed RedHat name for osfamily case f382af838e5c3fde51dba68b96d3315c5f8a28f6 Merge pull request #136 from justinstoller/maint/master/geppetto-update 978ae3f0e908d91e1174177d1de8992a9e4530f9 Update for using Geppetto plugin in CI a5361efdc41fabe74d9932bd39d489b2cf6c49b6 FM-1523: Added module summary to metadata.json 2e864d9c8fe8fcc0911caaa8fedcef57ead5659f Merge pull request #133 from justinstoller/maint/master/config_gem_mirror 5d05217bc7d4cdd0b80a7a7a454e06a99dc32ddd (maint) Allow setting gem mirror via GEM_SOURCE env var 523cc405b955d6bd6ed02fb71f9effc01341ff76 Add no port balancermember in readme.md cc2d534100ba9e3b1f3f0b0f32518b648b8fb660 Merge pull request #131 from mhaskel/test f19330d13ce8f1e7292aea0987207d2e0c729fe3 Merge pull request #130 from mhaskel/1.1.0-prep dd3b41d2749d4ec6ba765cfd8f2bd3fc9d1925ed 1.1.0 prep f8e4e26e150d2183498f20e255e597f84ddafe7c Merge pull request #129 from blkperl/remove_concat_dep_warnings 83048315c6a46fa73359629850024f24a683f340 Remove deprecated concat::setup class 899891c56086c2246a6462a17911832d7732267a Merge pull request #119 from Spredzy/more_listen_flexibility 5f07d772288dc5c3ed73c6000e0f29f1cbf3abb7 Allow greater flexibility in listen directive. 35c2a4c5613a4452cc1966176cb8524966a35f5f Merge pull request #123 from mhaskel/spec_updates c0d0586eb3c4f9379ed08941a5fc4453d948dff2 Spec updates for consistency f1b6cb225d958ba61fd235fd0cf5ae0790498bdb Add support for loadbalancer member without ports cec351cc379149a87af42235a00ad13ab7f4c5af Change include to include? a81cc1f939f2bca82ea53d291ddf19de8a3babb3 Merge pull request #118 from hunner/patch_helper 81511af979375684e222f3a64ba8249fb9729ad2 The spec helper should only run on supported platforms 8bcc83f6aac48475b6d782a768408fea37ffaf61 Merge pull request #117 from hunner/patch_cent5 f27cfd4b20cba35499e1bf3a240137187bbae47e CentOS 5 gets haproxy from epel 0bf92744a813614526fc98dff4553872c8e268f0 Merge pull request #116 from hunner/patch_rhel7 97db9816a55190d7ce5d53220023bb009403986d Rearrange helper to run tests standalone 9fe30efc1e8e9025ed0f3048441a49c668255c24 Merge pull request #115 from hunner/release_1.0.0 8d825258dc6dff88f8d84250e89e8d088646a659 Release 1.0.0 a64d144a3ac3f4ceb942c439220548dd4ec14cb2 Merge pull request #114 from hunner/add_support 4fd579b69be2ea3e498be961e2a98e9b3afe6f4d Add redhat 7 and ubuntu 14.04 compatibility info 53cdf8c05433cc260778f5788d0247eae4c19196 Merge pull request #113 from hunner/some_lint c0485e827d05cb2c1df1c7797a8678ee6194ae3b A few variable linting issues 98e1de9919a2b6e4d0ad1fac4db402f4d1fe0ff4 Merge pull request #112 from hunner/test_windows 59540935584366fb57ead1ecf178a04c256757fc Test that windows receives the incompatibility failure 8d59be6a8f5acf4685bba32fef3169fe925f320f Merge pull request #111 from adamcrews/docs d19a42386c49ca258da218b3ab6355433fa01a8b Fix concat module name in the docs a6b72da28f465c5e92ac91924d32f3599ddb20c1 Merge pull request #110 from hunner/patch_specs 546b68e333e34a0ef3d5dcfb802ecd51351f27c4 OSX not compatible, and windows doesn't have hieraconf 2dc1ec931644657148dcc8f4b1b4c2a274787e4e Merge pull request #109 from hunner/patch_specs 769cd4b31b369e9c86c791b2818b59ca348cae1e Add backports for debian testing 98741fc96980c0ce035b00af6c504309cfc7a9f0 Merge pull request #108 from hunner/redhat_userlist d6be9278318c186f75a79c5b1e54f78cd43e907b Disable userlist tests on rhel5 osfamily 43515e97ebcefc3f10a46773717128ed2b3e68e3 Merge pull request #107 from hunner/patch_specs f94bb2bbecd5737a7aec0dabcb3b493a0840b1a1 Add checks for passive failover and PE module paths 8007cb5037ffb2060d849e7f593779ec708c2ded Merge pull request #106 from hunner/fix_comp 8ef015ebceeb429575c0d5c544bfbca8f88ae094 Only support PE 3.3.x 191d1258ceb53848d16389add87653e524b2bd3e Merge pull request #105 from justinstoller/maint/master/hiera_conf_loc e9b999f03ee434a21637fad8ed954f162ab190f7 dont assume foss paths 55430b93c054f4140e65e6ce3d256c299c1cde2f Merge pull request #104 from hunner/readme 6b393d45c10d78b49a33623835450615f246f6ef Add puppet code types to readme 6beef5dfc2018e3d3253222492daf3aa92d7bd53 Update README for clarity and adherence to the style guide 5c6e920271d43fd79f647efe31274c67f79d7d7b Merge pull request #103 from hunner/patch_specs 10eb90add194288b889bf3adf19d092a5f3ceab4 Update specs to work on more operatingsystems 7022305f600fdd60d00b98d3baba9ce71ac9fdd2 Merge pull request #101 from puppetlabs/fix_metadata 4f228fc1bbd09ff20cba8d90e665564333d3cc7e Fix the metadata after build 239e754b030d477a1e873235ac9fd4307b736dc4 Merge pull request #100 from apenney/051-release 95a1ffe49f8e45fa69e3c9a4de4fa47c2dcac7d1 Prepare a 0.5.1 release. 9a6b21254b03135b10c4878e3eadc87d9b2a0e36 Merge pull request #98 from adamgraves85/fix/lint 05f147a1d9467080a79db3cb1f1a14449698770d Fix puppet-lint tests 3d3613d5edcba2e244238b27886eb88d52faedc6 Merge pull request #97 from hunner/update_specs fa6e2aa3c3430c0981603e0e814a65e886d881c8 Update specs with lots of test cases 65c996294e8de450929f62131b0f6f81280c4be0 Merge pull request #92 from hunner/mix_backends 32de3b29101bb1132e24d64e56528d892002a2fa Merge pull request #95 from hunner/private_define 3270ece47565919e3b6064bbc4b0195fd3384cc4 Merge pull request #96 from hunner/update_readme ade3c23f6371fb898351ef025dcc898f0a803510 Correctly privetize define f718b5c76cbfa75db6f6dddaaf9554791d733ac8 Update the readme to look something like the readme template adf59afbf319b18916eeedb5a51035433d18f574 Merge pull request #94 from hunner/bind_options fc1166f28d411dfd4f59d4bfd6936595c014a11b Add bind_options for frontends ef8316ddf741bb9f259f3607085f359250191050 Merge pull request #93 from hunner/fix_backend_port 451edd64f78cc15a6971e8ef5cf63d9d3185de74 Define each server/port combination on its own line 2829ce1b6310a3c08eac8aa66b78c19f68ff78cc Avoid mixing up backend servers f119b0126ea8408ad91e8cb4f312dba5d2ecf8f1 Merge pull request #91 from hunner/fragment_templates 87c03145661cc88f55d518779f7d819986c9476b Reduce template code duplication a85f1aa82250b3f1fa7875c6bced01228dd89866 Merge pull request #89 from hunner/add_config 0dd560cf1bce2374d229470c73d60e12d4d866bb Add custom_fragment parameter 2199ec81af539668a1db5521d458eb2edba47ceb Merge pull request #85 from 3dna/userlist c2e416f16c74cf3706e6b34a3e39ce5b9ebf10be force userlist to be more orderly in the overall config 4d8cdaebe244a483852dda24e94b5ce714793291 Merge pull request #87 from hunner/fix_perms dff6f0114af237183c4e7354c50bdb170954fab8 Merge pull request #88 from hunner/fix_mkdir 9013cf56ade620a28baf8067d7453b33d11d70d6 Add chroot ownership d23e468cc3816a3b743c4daa0fd559fd0e84177d Fix the mkdir for moduledir a7e30da60ddb049b33983c13fa50bebcb0be16a6 Merge pull request #81 from yasn77/master a4f8f2a89605a874ca6782ba25e3c6ac27e588ee Merge pull request #69 from lboynton/patch-1 c78c84df8266d9646dcd1a71935605849767e6d3 Merge pull request #86 from mhaskel/0.5.0-prep edc796be1c96253a1dec93d883adda3eb5c56ebd Prepare for 0.5.0 release. bde1970f0bd3fd1cf63cb7bc1dca3ba4d1800afc haproxy::userlist resource b35edfa71b9774f8f6e43b792a169405423980ac Merge pull request #82 from misterdorm/bindoptions 78c0e2a31877a3e73d7e506cc5b7d6ee1c5d38dc trailing whitespace cleanup 316959e6752700166e8d25925fca33b5824d3c0c ELS-1058 rspec for haproxy::listen bind_options parameter a5c61f2db852581572d4d9ef8a036dfa81436510 ELS-1058 haproxy bind options parameter 5099b354f64da8e6fe7f704219aa67c7a0ecf5cb Remove warnings when storeconfigs is not being used ff713f85d8fac7ade808f3d65d949a1a06b8ea88 Merge pull request #80 from hunner/do_conf_on_enable_false 8b452e30f1e54f585c8d2f3bb1a7dd3ea1cfe64e Add beaker tests ddce2ad12d34054480ade55194eba1c3e653127e Update module for install/config/service pattern & deprecate parameters b9a33671152aaf7b3890ec03c2ab564f67c940bd Allow the fact to manage but disable the haproxy service b09e12197421dcd9be70e670d9d4078deb6d9cc4 Merge pull request #79 from kurthuwig/remove-redundant-parameters 0dfc3ecadd8cc4786fc840fb447304fbb33fae9a Merge pull request #66 from toabctl/add-missing-license acb465199cd8cfc6b24989f92a6c159cbc36ae6c Merge pull request #57 from songkick/restart-command bd9bf99278bbd9fc2d4fbe5daa077d5e9b187972 Remove redundant params section d83b9e5e017f1238fab71d0c9c94f0f3f5b5b5e4 Merge pull request #78 from blkperl/add_travis_image 122cf569658795cc4f17c762406100b04883fce8 Merge pull request #77 from blkperl/fix_travis cdab83bdc1a05738ddf883a1bba56827fb6c43a4 Add Travis build status to README 51e6d13d21e4c3319531439b4da78fdcc07520dd Pin Rake to ~> 10.1.0 to support Ruby 1.8.7 399e564fa5f214245446e0624df4d7b176150efe Correct readme port 732d5a154817fe6aa7bb9b44c510f31f9068a04b Merge pull request #70 from aboe76/archlinux_support 5dc2a10b9cdfc417c4f16318173cdbb966e54974 Merge pull request #67 from retr0h/retr0h/deprecation-warnings 42f0917812e852299c2774ae35b7ee10d8ab81f8 Merge pull request #68 from retr0h/retr0h/standardize-module-docs e8f2b36b5fb2258ee5034dbac8431c555f408f07 Archlinux Support added. ed1d9c716c99494c857655769a92c8d127a029bd Fix ordering of options changing 16936bde32f99fac5c701c0f6097cc9f9231e002 (MODULES-433) Moved from `#include_class` to `#contain_class` 37bb671b392291ff5f5218bc5ee8003eed2582fb (doc) Standardized haproxy module docs 2417b39d95bce5b0bf1f494a2e0b4d2749768c27 Add missing LICENSE file 0d4c50ed56f4fce06b66c04611cebec29f7a37a8 Merge pull request #60 from mmz-srf/support-minus-in-service-names a950577fa6b619e61e64425bc112621efa9a7c5a Update test examples to check for the added '-01' 3cc389e8870ec18ac8f877cc3ff62a2d04406dec Reference release 1.0.0 in fixtures 2d416848f102a4cfd4509bf2bbf1fe4be01e8ed2 Change the order concat fragments of listening services are collected. c301a8528362706263a80de5446a3717f701971d Allow user-defined service restart parameter. 41d070ac088acffa26fdec884a2a5092e4dc6d4f Merge pull request #56 from apenney/041-release a3ddd3223be22220c7cc71d25f490eb77692ea65 Prepare 0.4.1 release. 5d9256e53e13467584438a781810190dc4b23819 Merge pull request #55 from hunner/fix_deps 05ea4669f1e8efcccaa6d042ffddd31e21650e03 Use puppetlabs/concat cc168275a56829dfb4fe37cf7ccf0382cef4d0bf Merge pull request #51 from songkick/master 19daa462750a3652468d4c7f03e58f0dfe053357 Merge pull request #53 from apenney/040-release 7d910f52e7dac39f3c836747cb0ac450da73f8e5 Prepare 0.4.0 release. 125e28fb51c03075a67ffb733516d3fe90684f7d Merge pull request #54 from apenney/travis deb8f81698adcb4c5b4d8d34755ce858971ca0ce Update travis, add Gemfile. 14ff37af2edf1b25abc8b37c8fe4a658f5587295 Fix test description bb531b37833dda1909ca22caecdd228de5675fce Merge pull request #45 from godp1301/patch-2 6caa933d463fdcad5719ea97908cfd5d5bb3e8da Update CHANGELOG 4b8159a3be69eff0c764e9c08a6ada66614abcec Merge pull request #42 from rharrison10/rharrison/pkg_name 832e25eb1398aa6a8616659855a77bcfc4239a73 Add parameter to specify an alternate package name to install Signed-off-by: Gael Chamoulaud --- Puppetfile | 2 +- haproxy/.fixtures.yml | 7 +- haproxy/.gemfile | 5 - haproxy/.geppetto-rc.json | 9 + haproxy/.gitignore | 9 + haproxy/.nodeset.yml | 20 + haproxy/.travis.yml | 34 +- haproxy/CHANGELOG | 18 - haproxy/CHANGELOG.md | 100 ++++ haproxy/CONTRIBUTING.md | 220 ++++++++ haproxy/Gemfile | 31 ++ haproxy/LICENSE | 201 +++++++ haproxy/Modulefile | 12 - haproxy/README.md | 507 ++++++++++++++++-- haproxy/Rakefile | 9 + haproxy/lib/facter/haproxy_version.rb | 22 + haproxy/manifests/backend.pp | 29 +- haproxy/manifests/balancermember.pp | 55 +- .../balancermember/collect_exported.pp | 8 + haproxy/manifests/config.pp | 34 ++ haproxy/manifests/frontend.pp | 63 ++- haproxy/manifests/init.pp | 155 +++--- haproxy/manifests/install.pp | 11 + haproxy/manifests/listen.pp | 71 ++- haproxy/manifests/params.pp | 47 +- haproxy/manifests/peer.pp | 16 + haproxy/manifests/peer/collect_exported.pp | 8 + haproxy/manifests/peers.pp | 17 + haproxy/manifests/service.pp | 28 + haproxy/manifests/userlist.pp | 41 ++ haproxy/metadata.json | 73 +++ haproxy/spec/acceptance/basic_spec.rb | 93 ++++ haproxy/spec/acceptance/frontbackend_spec.rb | 80 +++ haproxy/spec/acceptance/listen_spec.rb | 103 ++++ .../acceptance/nodesets/centos-5-vcloud.yml | 15 + .../acceptance/nodesets/centos-59-x64.yml | 10 + .../acceptance/nodesets/centos-6-vcloud.yml | 15 + .../acceptance/nodesets/centos-64-x64-pe.yml | 12 + .../acceptance/nodesets/centos-64-x64.yml | 10 + .../acceptance/nodesets/centos-65-x64.yml | 10 + .../acceptance/nodesets/debian-6-vcloud.yml | 15 + .../acceptance/nodesets/debian-7-vcloud.yml | 15 + haproxy/spec/acceptance/nodesets/default.yml | 10 + .../acceptance/nodesets/redhat-7-vcloud.yml | 15 + .../nodesets/ubuntu-1004-x86_64-vcloud.yml | 15 + .../nodesets/ubuntu-1404-x86_64-vcloud.yml | 15 + .../nodesets/ubuntu-server-10044-x64.yml | 10 + .../nodesets/ubuntu-server-12042-x64.yml | 10 + .../nodesets/ubuntu-server-1404-x64.yml | 11 + haproxy/spec/acceptance/unsupported_spec.rb | 11 + haproxy/spec/acceptance/userlist_spec.rb | 78 +++ haproxy/spec/classes/haproxy_spec.rb | 251 ++++++++- haproxy/spec/defines/backend_spec.rb | 29 +- haproxy/spec/defines/balancermember_spec.rb | 46 +- haproxy/spec/defines/frontend_spec.rb | 172 +++++- haproxy/spec/defines/listen_spec.rb | 200 ++++++- haproxy/spec/defines/peer_spec.rb | 40 ++ haproxy/spec/defines/peers_spec.rb | 15 + haproxy/spec/defines/userlist_spec.rb | 36 ++ haproxy/spec/spec_helper_acceptance.rb | 78 +++ .../spec/unit/facter/haproxy_version_spec.rb | 27 + haproxy/templates/fragments/_bind.erb | 23 + haproxy/templates/fragments/_mode.erb | 3 + haproxy/templates/fragments/_options.erb | 5 + haproxy/templates/haproxy-base.cfg.erb | 4 + haproxy/templates/haproxy_backend_block.erb | 6 +- haproxy/templates/haproxy_balancermember.erb | 8 +- haproxy/templates/haproxy_frontend_block.erb | 14 +- haproxy/templates/haproxy_listen_block.erb | 14 +- haproxy/templates/haproxy_peer.erb | 3 + haproxy/templates/haproxy_peers_block.erb | 2 + haproxy/templates/haproxy_userlist_block.erb | 12 + 72 files changed, 3034 insertions(+), 369 deletions(-) delete mode 100644 haproxy/.gemfile create mode 100644 haproxy/.geppetto-rc.json create mode 100644 haproxy/.gitignore create mode 100644 haproxy/.nodeset.yml delete mode 100644 haproxy/CHANGELOG create mode 100644 haproxy/CHANGELOG.md create mode 100644 haproxy/CONTRIBUTING.md create mode 100644 haproxy/Gemfile create mode 100644 haproxy/LICENSE delete mode 100644 haproxy/Modulefile create mode 100644 haproxy/lib/facter/haproxy_version.rb create mode 100644 haproxy/manifests/balancermember/collect_exported.pp create mode 100644 haproxy/manifests/config.pp create mode 100644 haproxy/manifests/install.pp create mode 100644 haproxy/manifests/peer.pp create mode 100644 haproxy/manifests/peer/collect_exported.pp create mode 100644 haproxy/manifests/peers.pp create mode 100644 haproxy/manifests/service.pp create mode 100644 haproxy/manifests/userlist.pp create mode 100644 haproxy/metadata.json create mode 100644 haproxy/spec/acceptance/basic_spec.rb create mode 100644 haproxy/spec/acceptance/frontbackend_spec.rb create mode 100644 haproxy/spec/acceptance/listen_spec.rb create mode 100644 haproxy/spec/acceptance/nodesets/centos-5-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/centos-59-x64.yml create mode 100644 haproxy/spec/acceptance/nodesets/centos-6-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/centos-64-x64-pe.yml create mode 100644 haproxy/spec/acceptance/nodesets/centos-64-x64.yml create mode 100644 haproxy/spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 haproxy/spec/acceptance/nodesets/debian-6-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/debian-7-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/default.yml create mode 100644 haproxy/spec/acceptance/nodesets/redhat-7-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/ubuntu-1004-x86_64-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/ubuntu-1404-x86_64-vcloud.yml create mode 100644 haproxy/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml create mode 100644 haproxy/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml create mode 100644 haproxy/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml create mode 100644 haproxy/spec/acceptance/unsupported_spec.rb create mode 100644 haproxy/spec/acceptance/userlist_spec.rb create mode 100644 haproxy/spec/defines/peer_spec.rb create mode 100644 haproxy/spec/defines/peers_spec.rb create mode 100644 haproxy/spec/defines/userlist_spec.rb create mode 100644 haproxy/spec/spec_helper_acceptance.rb create mode 100644 haproxy/spec/unit/facter/haproxy_version_spec.rb create mode 100644 haproxy/templates/fragments/_bind.erb create mode 100644 haproxy/templates/fragments/_mode.erb create mode 100644 haproxy/templates/fragments/_options.erb create mode 100644 haproxy/templates/haproxy_peer.erb create mode 100644 haproxy/templates/haproxy_peers_block.erb create mode 100644 haproxy/templates/haproxy_userlist_block.erb diff --git a/Puppetfile b/Puppetfile index 2fefa36de..477dc87cb 100644 --- a/Puppetfile +++ b/Puppetfile @@ -47,7 +47,7 @@ mod 'gnocchi', :git => 'https://github.com/stackforge/puppet-gnocchi.git' mod 'haproxy', - :commit => 'f381510e940ee11feb044c1c728ba2e5af807c79', + :commit => 'cf5c18ca25b8bb201e2dc61af5a938fe5b05ba70', :git => 'https://github.com/puppetlabs/puppetlabs-haproxy.git' mod 'heat', diff --git a/haproxy/.fixtures.yml b/haproxy/.fixtures.yml index 8d6f22d6f..c682e73b6 100644 --- a/haproxy/.fixtures.yml +++ b/haproxy/.fixtures.yml @@ -1,5 +1,10 @@ fixtures: repositories: - concat: "git://github.com/ripienaar/puppet-concat.git" + concat: + repo: "git://github.com/puppetlabs/puppetlabs-concat.git" + ref: '1.0.0' + stdlib: + repo: "git://github.com/puppetlabs/puppetlabs-stdlib.git" + ref: '2.4.0' symlinks: haproxy: "#{source_dir}" diff --git a/haproxy/.gemfile b/haproxy/.gemfile deleted file mode 100644 index 9aad840c0..000000000 --- a/haproxy/.gemfile +++ /dev/null @@ -1,5 +0,0 @@ -source :rubygems - -puppetversion = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : ['>= 2.7'] -gem 'puppet', puppetversion -gem 'puppetlabs_spec_helper', '>= 0.1.0' diff --git a/haproxy/.geppetto-rc.json b/haproxy/.geppetto-rc.json new file mode 100644 index 000000000..7df232989 --- /dev/null +++ b/haproxy/.geppetto-rc.json @@ -0,0 +1,9 @@ +{ + "excludes": [ + "**/contrib/**", + "**/examples/**", + "**/tests/**", + "**/spec/**", + "**/pkg/**" + ] +} diff --git a/haproxy/.gitignore b/haproxy/.gitignore new file mode 100644 index 000000000..b5db85e05 --- /dev/null +++ b/haproxy/.gitignore @@ -0,0 +1,9 @@ +pkg/ +Gemfile.lock +vendor/ +spec/fixtures/ +.vagrant/ +.bundle/ +coverage/ +.idea/ +*.iml diff --git a/haproxy/.nodeset.yml b/haproxy/.nodeset.yml new file mode 100644 index 000000000..481ba4c0d --- /dev/null +++ b/haproxy/.nodeset.yml @@ -0,0 +1,20 @@ +--- +default_set: 'centos-64-x64' +sets: + 'centos-64-x64': + nodes: + "main.foo.vm": + prefab: 'centos-64-x64' + 'multi-centos-64-x64': + default_node: 'lb' + nodes: + "lb": + prefab: 'centos-64-x64' + "slave1": + prefab: 'centos-64-x64' + "slave2": + prefab: 'centos-64-x64' + 'ubuntu-server-12042-x64': + nodes: + "main.foo.vm": + prefab: 'ubuntu-server-12042-x64' diff --git a/haproxy/.travis.yml b/haproxy/.travis.yml index fdbc95dc6..6cf8b0044 100644 --- a/haproxy/.travis.yml +++ b/haproxy/.travis.yml @@ -1,23 +1,17 @@ +--- language: ruby -rvm: - - 1.8.7 - - 1.9.3 -script: "rake spec" -branches: - only: - - master -env: - - PUPPET_VERSION=2.6.17 - - PUPPET_VERSION=2.7.19 - #- PUPPET_VERSION=3.0.1 # Breaks due to rodjek/rspec-puppet#58 -notifications: - email: false -gemfile: .gemfile +bundler_args: --without system_tests +script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--format documentation'" matrix: - exclude: - - rvm: 1.9.3 - gemfile: .gemfile - env: PUPPET_VERSION=2.6.17 + fast_finish: true + include: + - rvm: 1.8.7 + env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.6.0" - rvm: 1.8.7 - gemfile: .gemfile - env: PUPPET_VERSION=3.0.1 + env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.7.0" + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0" +notifications: + email: false diff --git a/haproxy/CHANGELOG b/haproxy/CHANGELOG deleted file mode 100644 index 99a992b2f..000000000 --- a/haproxy/CHANGELOG +++ /dev/null @@ -1,18 +0,0 @@ -2013-05-25 - Version 0.3.0 -Features: -- Add travis testing -- Add `haproxy::basancermember` `define_cookies` parameter -- Add array support to `haproxy::listen` `ipaddress` parameter - -Bugfixes: -- Documentation -- Listen -> Balancermember dependency -- Config line ordering -- Whitespace -- Add template lines for `haproxy::listen` `mode` parameter - -2012-10-12 - Version 0.2.0 -- Initial public release -- Backwards incompatible changes all around -- No longer needs ordering passed for more than one listener -- Accepts multiple listen ips/ports/server_names diff --git a/haproxy/CHANGELOG.md b/haproxy/CHANGELOG.md new file mode 100644 index 000000000..217aedfb1 --- /dev/null +++ b/haproxy/CHANGELOG.md @@ -0,0 +1,100 @@ +##2014-11-04 - Supported Release 1.1.0 +###Summary + +This release primarily adds greater flexibility in the listen directive. + +####Features +- Added `bind` parameter to `haproxy::frontend` + +####Deprecations +- `bind_options` in `haproxy::frontend` is being deprecated in favor of `bind` +- Remove references to deprecated concat::setup class and update concat dependency + +##2014-07-21 - Supported Release 1.0.0 +###Summary + +This supported release is the first stable release of haproxy! The updates to +this release allow you to customize pretty much everything that HAProxy has to +offer (that we could find at least). + +####Features +- Brand new readme +- Add haproxy::userlist defined resource for managing users +- Add haproxy::frontend::bind_options parameter +- Add haproxy::custom_fragment parameter for arbitrary configuration +- Add compatibility with more recent operating system releases + +####Bugfixes +- Check for listen/backend with the same names to avoid misordering +- Removed warnings when storeconfigs is not being used +- Passing lint +- Fix chroot ownership for global user/group +- Fix ability to uninstall haproxy +- Fix some linting issues +- Add beaker-rspec tests +- Increase unit test coverage +- Fix balancermember server lines with multiple ports + +##2014-05-28 - Version 0.5.0 +###Summary + +The primary feature of this release is a reorganization of the +module to match best practices. There are several new parameters +and some bug fixes. + +####Features +- Reorganized the module to follow install/config/service pattern +- Added bind_options parameter to haproxy::listen +- Updated tests + +####Fixes +- Add license file +- Whitespace cleanup +- Use correct port in README +- Fix order of concat fragments + +##2013-10-08 - Version 0.4.1 + +###Summary + +Fix the dependency for concat. + +####Fixes +- Changed the dependency to be the puppetlabs/concat version. + +##2013-10-03 - Version 0.4.0 + +###Summary + +The largest feature in this release is the new haproxy::frontend +and haproxy::backend defines. The other changes are mostly to +increase flexibility. + +####Features +- Added parameters to haproxy: + - `package_name`: Allows alternate package name. +- Add haproxy::frontend and haproxy::backend defines. +- Add an ensure parameter to balancermember so they can be removed. +- Made chroot optional + +####Fixes +- Remove deprecation warnings from templates. + +##2013-05-25 - Version 0.3.0 +####Features +- Add travis testing +- Add `haproxy::balancermember` `define_cookies` parameter +- Add array support to `haproxy::listen` `ipaddress` parameter + +####Bugfixes +- Documentation +- Listen -> Balancermember dependency +- Config line ordering +- Whitespace +- Add template lines for `haproxy::listen` `mode` parameter + +##2012-10-12 - Version 0.2.0 +- Initial public release +- Backwards incompatible changes all around +- No longer needs ordering passed for more than one listener +- Accepts multiple listen ips/ports/server_names diff --git a/haproxy/CONTRIBUTING.md b/haproxy/CONTRIBUTING.md new file mode 100644 index 000000000..f1cbde4bb --- /dev/null +++ b/haproxy/CONTRIBUTING.md @@ -0,0 +1,220 @@ +Checklist (and a short version for the impatient) +================================================= + + * Commits: + + - Make commits of logical units. + + - Check for unnecessary whitespace with "git diff --check" before + committing. + + - Commit using Unix line endings (check the settings around "crlf" in + git-config(1)). + + - Do not check in commented out code or unneeded files. + + - The first line of the commit message should be a short + description (50 characters is the soft limit, excluding ticket + number(s)), and should skip the full stop. + + - Associate the issue in the message. The first line should include + the issue number in the form "(#XXXX) Rest of message". + + - The body should provide a meaningful commit message, which: + + - uses the imperative, present tense: "change", not "changed" or + "changes". + + - includes motivation for the change, and contrasts its + implementation with the previous behavior. + + - Make sure that you have tests for the bug you are fixing, or + feature you are adding. + + - Make sure the test suites passes after your commit: + `bundle exec rspec spec/acceptance` More information on [testing](#Testing) below + + - When introducing a new feature, make sure it is properly + documented in the README.md + + * Submission: + + * Pre-requisites: + + - Make sure you have a [GitHub account](https://github.com/join) + + - [Create a ticket](https://tickets.puppetlabs.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppetlabs.com/browse/) you are patching for. + + * Preferred method: + + - Fork the repository on GitHub. + + - Push your changes to a topic branch in your fork of the + repository. (the format ticket/1234-short_description_of_change is + usually preferred for this project). + + - Submit a pull request to the repository in the puppetlabs + organization. + +The long version +================ + + 1. Make separate commits for logically separate changes. + + Please break your commits down into logically consistent units + which include new or changed tests relevant to the rest of the + change. The goal of doing this is to make the diff easier to + read for whoever is reviewing your code. In general, the easier + your diff is to read, the more likely someone will be happy to + review it and get it into the code base. + + If you are going to refactor a piece of code, please do so as a + separate commit from your feature or bug fix changes. + + We also really appreciate changes that include tests to make + sure the bug is not re-introduced, and that the feature is not + accidentally broken. + + Describe the technical detail of the change(s). If your + description starts to get too long, that is a good sign that you + probably need to split up your commit into more finely grained + pieces. + + Commits which plainly describe the things which help + reviewers check the patch and future developers understand the + code are much more likely to be merged in with a minimum of + bike-shedding or requested changes. Ideally, the commit message + would include information, and be in a form suitable for + inclusion in the release notes for the version of Puppet that + includes them. + + Please also check that you are not introducing any trailing + whitespace or other "whitespace errors". You can do this by + running "git diff --check" on your changes before you commit. + + 2. Sending your patches + + To submit your changes via a GitHub pull request, we _highly_ + recommend that you have them on a topic branch, instead of + directly on "master". + It makes things much easier to keep track of, especially if + you decide to work on another thing before your first change + is merged in. + + GitHub has some pretty good + [general documentation](http://help.github.com/) on using + their site. They also have documentation on + [creating pull requests](http://help.github.com/send-pull-requests/). + + In general, after pushing your topic branch up to your + repository on GitHub, you can switch to the branch in the + GitHub UI and click "Pull Request" towards the top of the page + in order to open a pull request. + + + 3. Update the related GitHub issue. + + If there is a GitHub issue associated with the change you + submitted, then you should update the ticket to include the + location of your branch, along with any other commentary you + may wish to make. + +Testing +======= + +Getting Started +--------------- + +Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby +package manager such as [bundler](http://bundler.io/) what Ruby packages, +or Gems, are required to build, develop, and test this software. + +Please make sure you have [bundler installed](http://bundler.io/#getting-started) +on your system, then use it to install all dependencies needed for this project, +by running + +```shell +% bundle install +Fetching gem metadata from https://rubygems.org/........ +Fetching gem metadata from https://rubygems.org/.. +Using rake (10.1.0) +Using builder (3.2.2) +-- 8><-- many more --><8 -- +Using rspec-system-puppet (2.2.0) +Using serverspec (0.6.3) +Using rspec-system-serverspec (1.0.0) +Using bundler (1.3.5) +Your bundle is complete! +Use `bundle show [gemname]` to see where a bundled gem is installed. +``` + +NOTE some systems may require you to run this command with sudo. + +If you already have those gems installed, make sure they are up-to-date: + +```shell +% bundle update +``` + +With all dependencies in place and up-to-date we can now run the tests: + +```shell +% rake spec +``` + +This will execute all the [rspec tests](http://rspec-puppet.com/) tests +under [spec/defines](./spec/defines), [spec/classes](./spec/classes), +and so on. rspec tests may have the same kind of dependencies as the +module they are testing. While the module defines in its [Modulefile](./Modulefile), +rspec tests define them in [.fixtures.yml](./fixtures.yml). + +Some puppet modules also come with [beaker](https://github.com/puppetlabs/beaker) +tests. These tests spin up a virtual machine under +[VirtualBox](https://www.virtualbox.org/)) with, controlling it with +[Vagrant](http://www.vagrantup.com/) to actually simulate scripted test +scenarios. In order to run these, you will need both of those tools +installed on your system. + +You can run them by issuing the following command + +```shell +% rake spec_clean +% rspec spec/acceptance +``` + +This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), +install puppet, copy this module and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb) +and then run all the tests under [spec/acceptance](./spec/acceptance). + +Writing Tests +------------- + +XXX getting started writing tests. + +If you have commit access to the repository +=========================================== + +Even if you have commit access to the repository, you will still need to +go through the process above, and have someone else review and merge +in your changes. The rule is that all changes must be reviewed by a +developer on the project (that did not write the code) to ensure that +all changes go through a code review process. + +Having someone other than the author of the topic branch recorded as +performing the merge is the record that they performed the code +review. + + +Additional Resources +==================== + +* [Getting additional help](http://puppetlabs.com/community/get-help) + +* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) + +* [Patchwork](https://patchwork.puppetlabs.com) + +* [General GitHub documentation](http://help.github.com/) + +* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) + diff --git a/haproxy/Gemfile b/haproxy/Gemfile new file mode 100644 index 000000000..62c569397 --- /dev/null +++ b/haproxy/Gemfile @@ -0,0 +1,31 @@ +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +group :development, :unit_tests do + gem 'rake', :require => false + gem 'rspec-core', '3.1.7', :require => false + gem 'rspec-puppet', '~> 1.0', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'puppet-lint', :require => false + gem 'simplecov', :require => false + gem 'puppet_facts', :require => false + gem 'json', :require => false +end + +group :system_tests do + gem 'beaker-rspec', :require => false + gem 'serverspec', :require => false +end + +if facterversion = ENV['FACTER_GEM_VERSION'] + gem 'facter', facterversion, :require => false +else + gem 'facter', :require => false +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/haproxy/LICENSE b/haproxy/LICENSE new file mode 100644 index 000000000..c4a243518 --- /dev/null +++ b/haproxy/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2012 Puppet Labs + + 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/haproxy/Modulefile b/haproxy/Modulefile deleted file mode 100644 index 7f70ac0c2..000000000 --- a/haproxy/Modulefile +++ /dev/null @@ -1,12 +0,0 @@ -name 'puppetlabs-haproxy' -version '0.3.0' -source 'git://github.com/puppetlabs/puppetlabs-haproxy' -author 'Puppet Labs' -license 'Apache License, Version 2.0' -summary 'Haproxy Module' -description 'An Haproxy module for Redhat family OSes using Storeconfigs' -project_page 'http://github.com/puppetlabs/puppetlabs-haproxy' - -## Add dependencies, if any: -# dependency 'username/name', '>= 1.2.0' -dependency 'ripienaar/concat', '>= 0.1.0' diff --git a/haproxy/README.md b/haproxy/README.md index 8e51edc5c..0e4db97cf 100644 --- a/haproxy/README.md +++ b/haproxy/README.md @@ -1,93 +1,496 @@ -PuppetLabs Module for haproxy -============================= +#haproxy -HAProxy is an HA proxying daemon for load-balancing to clustered services. It -can proxy TCP directly, or other kinds of traffic such as HTTP. +[![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-haproxy.svg?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-haproxy) -Basic Usage ------------ +####Table of Contents -This haproxy uses storeconfigs to collect and realize balancer member servers -on a load balancer server. Currently Redhat family OSes are supported. +1. [Overview](#overview) +2. [Module Description - What the module does and why it is useful](#module-description) +3. [Setup - The basics of getting started with haproxy](#setup) + * [Beginning with haproxy](#beginning-with-haproxy) +4. [Usage - Configuration options and additional functionality](#usage) + * [Configuring haproxy options](#configuring-haproxy-options) + * [Configuring an HAProxy daemon listener](#configuring-haproxy-daemon-listener) + * [Configuring HAProxy load-balanced member nodes](#configuring-haproxy-loadbalanced-member-nodes) + * [Configuring a load balancer with exported resources](#configuring-a-load-balancer-with-exported-resources) + * [Classes and Defined Types](#classes-and-defined-types) + * [Class: haproxy](#class-haproxy) + * [Defined Type: haproxy::balancermember](#defined-type-haproxybalancermember) + * [Defined Type: haproxy::backend](#defined-type-haproxybackend) + * [Defined type: haproxy::frontend](#defined-type-haproxyfrontend) + * [Defined type: haproxy::listen](#defined-type-haproxylisten) + * [Defined Type: haproxy::userlist](#define-type-haproxyuserlist) + * [Defined Type: haproxy::peers](#define-type-haproxypeers) + * [Defined Type: haproxy::peer](#define-type-haproxypeer) +5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) + * [Public classes and defined types](#public-classes-and-defined-types) + * [Private classes and defined types](#private-classes-and-defined-types) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) -*To install and configure HAProxy server listening on port 80* +##Overview + +The haproxy module provides the ability to install, configure, and manage HAProxy. + +##Module Description + +HAProxy is a daemon for load-balancing and proxying TCP and HTTP-based services. +This module configures proxy servers and manages the configuration of backend member servers. + +##Setup + +###Beginning with haproxy + +The quickest way to get up and running using the haproxy module is to install and configure a basic HAProxy server that is listening on port 8140 and balanced against two nodes. ```puppet node 'haproxy-server' { class { 'haproxy': } haproxy::listen { 'puppet00': - ipaddress => $::ipaddress, - ports => '8140', + collect_exported => false, + ipaddress => $::ipaddress, + ports => '8140', } + haproxy::balancermember { 'master00': + listening_service => 'puppet00', + server_names => 'master00.example.com', + ipaddresses => '10.0.0.10', + ports => '8140', + options => 'check', + } + haproxy::balancermember { 'master01': + listening_service => 'puppet00', + server_names => 'master01.example.com', + ipaddresses => '10.0.0.11', + ports => '8140', + options => 'check', + } +} +``` + +##Usage + +###Configuring haproxy options + +The main [`haproxy` class](#class-haproxy) has many options for configuring your HAProxy server. + +```puppet +class { 'haproxy': + global_options => { + 'log' => "${::ipaddress} local0", + 'chroot' => '/var/lib/haproxy', + 'pidfile' => '/var/run/haproxy.pid', + 'maxconn' => '4000', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'stats' => 'socket /var/lib/haproxy/stats', + }, + defaults_options => { + 'log' => 'global', + 'stats' => 'enable', + 'option' => 'redispatch', + 'retries' => '3', + 'timeout' => [ + 'http-request 10s', + 'queue 1m', + 'connect 10s', + 'client 1m', + 'server 1m', + 'check 10s', + ], + 'maxconn' => '8000', + }, +} +``` + +###Configuring HAProxy daemon listener + + +To export the resource for a balancermember and collect it on a single HAProxy load balancer server: + +```puppet +haproxy::listen { 'puppet00': + ipaddress => $::ipaddress, + ports => '18140', + mode => 'tcp', + options => { + 'option' => [ + 'tcplog', + 'ssl-hello-chk', + ], + 'balance' => 'roundrobin', + }, } ``` +###Configuring multi-network daemon listener -*To add backend loadbalance members* +One might have more advanced needs for the listen block, then use the `$bind` parameter: ```puppet -node 'webserver01' { - @@haproxy::balancermember { $fqdn: +haproxy::listen { 'puppet00': + mode => 'tcp', + options => { + 'option' => [ + 'tcplog', + 'ssl-hello-chk', + ], + 'balance' => 'roundrobin', + }, + bind => { + '10.0.0.1:443' => ['ssl', 'crt', 'puppetlabs.com'], + '168.12.12.12:80' => [], + '192.168.122.42:8000-8100' => ['ssl', 'crt', 'puppetlabs.com'], + ':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com'] + }, +} +``` +Note: `$ports` or `$ipaddress` and `$bind` are mutually exclusive + +###Configuring HAProxy load-balanced member nodes + +First, export the resource for a balancer member. + +```puppet +@@haproxy::balancermember { 'haproxy': + listening_service => 'puppet00', + ports => '8140', + server_names => $::hostname, + ipaddresses => $::ipaddress, + options => 'check', +} +``` + +Then, collect the resource on a load balancer. + +```puppet +Haproxy::Balancermember <<| listening_service == 'puppet00' |>> +``` + +Then, create the resource for multiple balancer members at once (this assumes a single-pass installation of HAProxy without requiring a first pass to export the resources, and is intended for situations where you know the members in advance). + +```puppet +haproxy::balancermember { 'haproxy': + listening_service => 'puppet00', + ports => '8140', + server_names => ['server01', 'server02'], + ipaddresses => ['192.168.56.200', '192.168.56.201'], + options => 'check', +} +``` +###Configuring a load balancer with exported resources + +Install and configure an HAProxy server listening on port 8140 and balanced against all collected nodes. This HAProxy uses storeconfigs to collect and realize balancermember servers on a load balancer server. + +```puppet +node 'haproxy-server' { + class { 'haproxy': } + haproxy::listen { 'puppet00': + ipaddress => $::ipaddress, + ports => '8140', + } +} + +node /^master\d+/ { + @@haproxy::balancermember { $::fqdn: listening_service => 'puppet00', server_names => $::hostname, ipaddresses => $::ipaddress, ports => '8140', - options => 'check' + options => 'check', } } ``` -Configuring haproxy options ---------------------------- +The resulting HAProxy server will automatically collect configurations from backend servers. The backend nodes will export their HAProxy configurations to the puppet master which will then distribute them to the HAProxy server. + +###Classes and Defined Types + +####Class: `haproxy` + +This is the main class of the module, guiding the installation and configuration of at least one HAProxy server. + +**Parameters:** + +#####`custom_fragment` +Allows arbitrary HAProxy configuration to be passed through to support additional configuration not otherwise available via parameters. Also allows arbitrary HAPRoxy configuration to short-circuit defined resources, such as `haproxy::listen`. Accepts a string (e.g. output from the template() function). Defaults to 'undef'. + +#####`defaults_options` +All the default haproxy options, displayed in a hash. If you want to specify more than one option (i.e. multiple timeout or stats options), pass those options as an array and you will get a line for each of them in the resulting haproxy.cfg file. + +#####`global_options` +All the haproxy global options, displayed in a hash. If you want to specify more than one option (i.e. multiple timeout or stats options), pass those options as an array and you will get a line for each of them in the resulting haproxy.cfg file. + +#####`package_ensure` +Determines whether the HAProxy package should be installed or uninstalled. Defaults to 'present'. + +#####`package_name` +Sets the HAProxy package name. Defaults to 'haproxy'. + +#####`restart_command` +Specifies the command to use when restarting the service upon config changes. Passed directly as the restart parameter to the service resource. Defaults to 'undef', i.e. whatever the service default is. + +#####`service_ensure` +Determines whether the HAProxy service should be running & enabled at boot, or stopped and disabled at boot. Defaults to 'running'. + +#####`service_manage` +Specifies whether the HAProxy service state should be managed by Puppet. Defaults to 'true'. + +####Defined Type: `haproxy::balancermember` + +This type will set up a balancermember inside a listening or backend service configuration block in /etc/haproxy/haproxy.cfg on the load balancer. Currently, it has the ability to specify the instance name, ip address, port, and whether or not it is a backup. + +Automatic discovery of balancermember nodes may be implemented by exporting the balancermember resource for all HAProxy balancer member servers and then collecting them on the main HAProxy load balancer. + +**Parameters:** + +#####`define_cookies` +Determines whether 'cookie SERVERID' stickiness options are added. Defaults to 'false'. + +#####`ensure` +Determines whether the balancermember should be present or absent. Defaults to 'present'. + +#####`ipaddresses` +Specifies the IP address used to contact the balancer member server. Can be an array. If this parameter is specified as an array it must be the same length as the [`server\_names`](#server_names) parameter's array. A balancermember is created for each pair of addresses. These pairs will be multiplied, and additional balancermembers created, based on the number of `ports` specified. + +#####`listening_service` +Sets the HAProxy service's instance name (or the title of the `haproxy::listen` resource). This must match a declared `haproxy::listen` resource. + +#####`name` +Specifies the title of the resource. The `name` is arbitrary and only utilized in the concat fragment name. + +#####`options` +An array of options to be specified after the server declaration in the listening service's configuration block. + +#####`ports` +Sets the ports on which the balancer member will accept connections from the load balancer. If ports are specified, it must be an array. If you use an array in `server\_names` and `ipaddresses`, the number of ports specified will multiply the number of balancermembers formed from the IP address and server name pairs. If no port is specified, the balancermember will receive the traffic on the same port the frontend receive it (Very useful if used with a frontend with multiple bind ports). + +#####`server_names` +Sets the name of the balancermember server in the listening service's configuration block. Defaults to the hostname. Can be an array. If this parameter is specified as an array, it must be the same length as the [`ipaddresses`](#ipaddresses) parameter's array. A balancermember is created for each pair of `server\_names` and `ipaddresses` in the array.hese pairs will be multiplied, and additional balancermembers created, based on the number of `ports` specified. + +####Defined Type: `haproxy::backend` + +This type sets up a backend service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each backend service needs one or more load balancer member servers (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type). + +Using storeconfigs, you can export the `haproxy::balancermember` resources on all load balancer member servers and collect them on a single HAProxy load balancer server. + +**Parameters** + +#####`name` +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. + +#####`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'. + +The 'true' value means exported balancermember resources, for the case when every balancermember node exports itself, will be collected. Whereas, 'false' means the existing declared balancermember resources will be relied on; this is meant for cases when you know the full set of balancermembers in advance and use `haproxy::balancermember` with array arguments, allowing you to deploy everything in a single run. + +#####Example + +To export the resource for a backend service member, + +```puppet +haproxy::backend { 'puppet00': + options => { + 'option' => [ + 'tcplog', + 'ssl-hello-chk', + ], + 'balance' => 'roundrobin', + }, +} +``` + +####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. + +**Parameters** + +#####`bind_options` +Lists an array of options to be specified after the bind declaration in the bind's configuration block. **Deprecated**: This parameter is being deprecated in favor of $bind + +#####`bind` +A hash of listening addresses/ports, and a list of parameters that make up the listen service's `bind` lines. This is the most flexible way to configure listening services in a frontend or listen directive. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4.2-bind for details. + +The hash keys represent the listening address and port, such as `192.168.122.1:80`, `10.1.1.1:8900-9000`, `:80,:8080` or `/var/run/haproxy-frontend.sock` and the key's value is an array of bind options for that listening address, such as `[ 'ssl', 'crt /etc/ssl/puppetlabs.com.crt', 'no-sslv3' ]`. Example: + +```puppet +bind => { + '168.12.12.12:80' => [], + '192.168.1.10:8080,192.168.1.10:8081' => [], + '10.0.0.1:443-453' => ['ssl', 'crt', 'puppetlabs.com'], + ':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com'], + '/var/run/haproxy-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ], +} +``` + +#####`ipaddress` +Specifies the IP address the proxy binds to. No value, '\*', and '0.0.0.0' mean that the proxy listens to all valid addresses on the system. + +#####`mode` +Sets the mode of operation for the frontend service. Valid values are 'undef', 'tcp', 'http', and 'health'. + +#####`name` +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. + +#####`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. + +#####Example + +To route traffic from port 8140 to all balancermembers added to a backend with the title 'puppet_backend00', + +```puppet +haproxy::frontend { 'puppet00': + ipaddress => $::ipaddress, + ports => '18140', + mode => 'tcp', + bind_options => 'accept-proxy', + options => { + 'option' => [ 'default_backend', 'puppet_backend00'], + 'timeout client' => '30', + 'balance' => 'roundrobin' + '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). + +Using storeconfigs, you can export the `haproxy::balancermember` resources on all load balancer member servers and collect them on a single HAProxy load balancer server. + +**Parameters:** + +#####`bind_options` +Sets the options to be specified after the bind declaration in the listening service's configuration block. Displays as an array. **Deprecated**: This parameter is being deprecated in favor of $bind + +#####`bind` +A hash of listening addresses/ports, and a list of parameters that make up the listen service's `bind` lines. This is the most flexible way to configure listening services in a frontend or listen directive. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4.2-bind for details. + +The hash keys represent the listening address and port, such as `192.168.122.1:80`, `10.1.1.1:8900-9000`, `:80,:8080` or `/var/run/haproxy-frontend.sock` and the key's value is an array of bind options for that listening address, such as `[ 'ssl', 'crt /etc/ssl/puppetlabs.com.crt', 'no-sslv3' ]`. Example: + +```puppet +bind => { + '168.12.12.12:80' => [], + '192.168.1.10:8080,192.168.1.10:8081' => [], + '10.0.0.1:443-453' => ['ssl', 'crt', 'puppetlabs.com'], + ':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com'], + '/var/run/haproxy-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ], +} +``` + +#####`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'. + +The 'true' value means exported balancermember resources, for the case when every balancermember node exports itself, will be collected. Whereas, 'false' means the existing declared balancermember resources will be relied on; this is meant for cases when you know the full set of balancermembers in advance and use `haproxy::balancermember` with array arguments, allowing you to deploy everything in a single run. + +#####`ipaddress` +Specifies the IP address the proxy binds to. No value, '\*', and '0.0.0.0' mean that the proxy listens to all valid addresses on the system. + +#####`mode` +Specifies the mode of operation for the listening service. Valid values are 'undef', 'tcp', 'http', and 'health'. + +#####`name` +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. + +#####`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. + +####Defined Type: `haproxy::userlist` + +This type sets up a [userlist configuration block](http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4) inside the haproxy.cfg file on an HAProxy load balancer. + +**Parameters:** + +#####`name` +Sets the userlist's name. Generally it will be the namevar of the defined resource type. This value appears right after the 'userlist' statement in haproxy.cfg + + +#####`users` +An array of users in the userlist. See http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4-user + +#####`groups` +An array of groups in the userlist. See http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4-group + + +####Defined Type: `haproxy::peers` + +This type will set up a peers entry in /etc/haproxy/haproxy.cfg on the load balancer. This setting is required to share the current state of HAproxy with other HAproxy in High available configurations. + +** parameters ** + +#####`name` +Sets the peers' name. Generally it will be the namevar of the defined resource type. This value appears right after the 'peers' statement in haproxy.cfg + + +####Defined Type: `haproxy::peer` + +This type will set up a peer entry inside the peers configuration block in /etc/haproxy/haproxy.cfg on the load balancer. Currently, it has the ability to specify the instance name, ip address, ports and server_names. + +Automatic discovery of peer nodes may be implemented by exporting the peer resource for all HAProxy balancer servers that are configured in the same HA block and then collecting them on all load balancers. -The base `haproxy` class can accept two parameters which will configure basic -behaviour of the haproxy server daemon: +**Parameters:** -- `global_options` to configure the `global` section in `haproxy.cfg` -- `defaults_options` to configure the `defaults` section in `haproxy.cfg` +#####`peers_name` +Specifies the peer in which this load balancer needs to be added. -Configuring haproxy daemon listener ------------------------------------ +#####`server_names` +Sets the name of the peer server in the peers configuration block. Defaults to the hostname. Can be an array. If this parameter is specified as an array, it must be the same length as the [`ipaddresses`](#ipaddresses) parameter's array. A peer is created for each pair of `server\_names` and `ipaddresses` in the array. -One `haproxy::listen` defined resource should be defined for each HAProxy loadbalanced set of backend servers. The title of the `haproxy::listen` resource is the key to which balancer members will be proxied to. The `ipaddress` field should be the public ip address which the loadbalancer will be contacted on. The `ports` attribute can accept an array or comma-separated list of ports which should be proxied to the `haproxy::balancermember` nodes. +####`ensure` +Whether to add or remove the peer. Defaults to 'present'. Valid values are 'present' and 'absent'. -Configuring haproxy daemon frontend ------------------------------------ +#####`ipaddresses` +Specifies the IP address used to contact the peer member server. Can be an array. If this parameter is specified as an array it must be the same length as the [`server\_names`](#server_names) parameter's array. A peer is created for each pair of address and server_name. -One `haproxy::frontend` defined resource should be defined for each HAProxy front end you wish to set up. The `ipaddress` field should be the public ip address which the loadbalancer will be contacted on. The `ports` attribute can accept an array or comma-separated list of ports which should be proxied to the `haproxy::backend` resources. +#####`ports` +Sets the port on which the peer is going to share the state. -Configuring haproxy daemon backend ----------------------------------- -One `haproxy::backend` defined resource should be defined for each HAProxy loadbalanced set of backend servers. The title of the `haproxy::backend` resource is the key to which balancer members will be proxied to. Note that an `haproxy::listen` resource and `haproxy::backend` resource *can* have the same name, and any balancermembers exported to that name will show up in both places. This is likely to have unsatisfactory results, but there's nothing preventing this from happening. +##Reference -Configuring haproxy loadbalanced member nodes ---------------------------------------------- +###Public classes and defined types -The `haproxy::balancermember` defined resource should be exported from each node -which is serving loadbalanced traffic. the `listening_service` attribute will -associate it with `haproxy::listen` directives on the haproxy node. -`ipaddresses` and `ports` will be assigned to the member to be contacted on. If an array of `ipaddresses` and `server_names` are provided then they will be added to the config in lock-step. +* Class `haproxy`: Main configuration class +* Define `haproxy::listen`: Creates a listen entry in the config +* Define `haproxy::frontend`: Creates a frontend entry in the config +* Define `haproxy::backend`: Creates a backend entry in the config +* Define `haproxy::balancermember`: Creates server entries for listen or backend blocks. +* Define `haproxy::userlist`: Creates a userlist entry in the config +* Define `haproxy::peers`: Creates a peers entry in the config +* Define `haproxy::peer`: Creates server entries for ha configuration inside peers. -Dependencies ------------- +###Private classes and defined types -Tested and built on Ubuntu and CentOS +* Class `haproxy::params`: Per-operatingsystem defaults. +* Class `haproxy::install`: Installs packages. +* Class `haproxy::config`: Configures haproxy.cfg. +* Class `haproxy::service`: Manages service. +* Define `haproxy::balancermember::collect_exported`: Collects exported balancermembers +* Define `haproxy::peer::collect_exported`: Collects exported peers -Copyright and License ---------------------- +##Limitations -Copyright (C) 2012 [Puppet Labs](https://www.puppetlabs.com/) Inc +RedHat and Debian family OSes are officially supported. Tested and built on Ubuntu and CentOS. -Puppet Labs can be contacted at: info@puppetlabs.com +##Development -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 +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. - http://www.apache.org/licenses/LICENSE-2.0 +We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. -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. +You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing) diff --git a/haproxy/Rakefile b/haproxy/Rakefile index cd3d37995..e3be95b0b 100644 --- a/haproxy/Rakefile +++ b/haproxy/Rakefile @@ -1 +1,10 @@ require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.fail_on_warnings +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_inherits_from_params_class') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] diff --git a/haproxy/lib/facter/haproxy_version.rb b/haproxy/lib/facter/haproxy_version.rb new file mode 100644 index 000000000..5797c16a6 --- /dev/null +++ b/haproxy/lib/facter/haproxy_version.rb @@ -0,0 +1,22 @@ +# Fact: haproxy_version +# +# Purpose: get haproxy's current version +# +# Resolution: +# Uses haproxy's -v flag and parses the result from 'version' +# +# Caveats: +# none +# +# Notes: +# None +if Facter::Util::Resolution.which('haproxy') + Facter.add('haproxy_version') do + haproxy_version_cmd = 'haproxy -v 2>&1' + haproxy_version_result = Facter::Util::Resolution.exec(haproxy_version_cmd) + setcode do + haproxy_version_result.to_s.lines.first.strip.split(/HA-Proxy/)[1].strip.split(/version/)[1].strip.split(/((\d+\.){2,}\d+).*/)[1] + end + end +end + diff --git a/haproxy/manifests/backend.pp b/haproxy/manifests/backend.pp index 3ae6781bd..8f4de386b 100644 --- a/haproxy/manifests/backend.pp +++ b/haproxy/manifests/backend.pp @@ -9,27 +9,26 @@ # # === Requirement/Dependencies: # -# Currently requires the ripienaar/concat module on the Puppet Forge and +# Currently requires the puppetlabs/concat module on the Puppet Forge and # uses storeconfigs on the Puppet Master to export/collect resources # from all backend members. # # === Parameters # # [*name*] -# The namevar of the defined resource type is the backend service's name. -# This name goes right after the 'backend' statement in haproxy.cfg +# The namevar of the defined resource type is the backend service's name. +# This name goes right after the 'backend' statement in haproxy.cfg # # [*options*] -# A hash of options that are inserted into the backend configuration block. +# A hash of options that are inserted into the backend configuration block. # # [*collect_exported*] -# Boolean, default 'true'. True means 'collect exported @@balancermember -# resources' (for the case when every balancermember node exports itself), -# false means 'rely on the existing declared balancermember resources' (for -# the case when you know the full set of balancermember in advance and use -# haproxy::balancermember with array arguments, which allows you to deploy -# everything in 1 run) -# +# Boolean, default 'true'. True means 'collect exported @@balancermember +# resources' (for the case when every balancermember node exports itself), +# false means 'rely on the existing declared balancermember resources' (for +# the case when you know the full set of balancermember in advance and use +# haproxy::balancermember with array arguments, which allows you to deploy +# everything in 1 run) # # === Examples # @@ -61,15 +60,19 @@ } ) { + if defined(Haproxy::Listen[$name]) { + fail("An haproxy::listen resource was discovered with the same name (${name}) which is not supported") + } + # Template uses: $name, $ipaddress, $ports, $options concat::fragment { "${name}_backend_block": order => "20-${name}-00", - target => '/etc/haproxy/haproxy.cfg', + target => $::haproxy::config_file, content => template('haproxy/haproxy_backend_block.erb'), } if $collect_exported { - Haproxy::Balancermember <<| listening_service == $name |>> + haproxy::balancermember::collect_exported { $name: } } # else: the resources have been created and they introduced their # concat fragments. We don't have to do anything about them. diff --git a/haproxy/manifests/balancermember.pp b/haproxy/manifests/balancermember.pp index 4fe949ae8..9c329129e 100644 --- a/haproxy/manifests/balancermember.pp +++ b/haproxy/manifests/balancermember.pp @@ -10,7 +10,7 @@ # # === Requirement/Dependencies: # -# Currently requires the ripienaar/concat module on the Puppet Forge and +# Currently requires the puppetlabs/concat module on the Puppet Forge and # uses storeconfigs on the Puppet Master to export/collect resources # from all balancer members. # @@ -21,39 +21,39 @@ # fragment name. # # [*listening_service*] -# The haproxy service's instance name (or, the title of the -# haproxy::listen resource). This must match up with a declared -# haproxy::listen resource. +# The haproxy service's instance name (or, the title of the +# haproxy::listen resource). This must match up with a declared +# haproxy::listen resource. # # [*ports*] -# An array or commas-separated list of ports for which the balancer member -# will accept connections from the load balancer. Note that cookie values -# aren't yet supported, but shouldn't be difficult to add to the -# configuration. If you use an array in server_names and ipaddresses, the -# same port is used for all balancermembers. +# An array or commas-separated list of ports for which the balancer member +# will accept connections from the load balancer. Note that cookie values +# aren't yet supported, but shouldn't be difficult to add to the +# configuration. If you use an array in server_names and ipaddresses, the +# same port is used for all balancermembers. # # [*server_names*] -# The name of the balancer member server as known to haproxy in the -# listening service's configuration block. This defaults to the -# hostname. Can be an array of the same length as ipaddresses, -# in which case a balancermember is created for each pair of -# server_names and ipaddresses (in lockstep). +# The name of the balancer member server as known to haproxy in the +# listening service's configuration block. This defaults to the +# hostname. Can be an array of the same length as ipaddresses, +# in which case a balancermember is created for each pair of +# server_names and ipaddresses (in lockstep). # # [*ipaddresses*] -# The ip address used to contact the balancer member server. -# Can be an array, see documentation to server_names. +# The ip address used to contact the balancer member server. +# Can be an array, see documentation to server_names. # # [*ensure*] -# If the balancermember should be present or absent. -# Defaults to present. +# If the balancermember should be present or absent. +# Defaults to present. # # [*options*] -# An array of options to be specified after the server declaration -# in the listening service's configuration block. +# An array of options to be specified after the server declaration +# in the listening service's configuration block. # # [*define_cookies*] -# If true, then add "cookie SERVERID" stickiness options. -# Default false. +# If true, then add "cookie SERVERID" stickiness options. +# Default false. # # === Examples # @@ -75,7 +75,7 @@ # Creating the resource for multiple balancer members at once # (for single-pass installation of haproxy without requiring a first # pass to export the resources if you know the members in advance): -# +# # haproxy::balancermember { 'haproxy': # listening_service => 'puppet00', # ports => '8140', @@ -83,23 +83,24 @@ # ipaddresses => ['192.168.56.200', '192.168.56.201'], # options => 'check', # } -# +# # (this resource can be declared anywhere) # define haproxy::balancermember ( $listening_service, - $ports, + $ports = undef, $server_names = $::hostname, $ipaddresses = $::ipaddress, $ensure = 'present', $options = '', $define_cookies = false ) { + # Template uses $ipaddresses, $server_name, $ports, $option concat::fragment { "${listening_service}_balancermember_${name}": - order => "20-${listening_service}-${name}", ensure => $ensure, - target => '/etc/haproxy/haproxy.cfg', + order => "20-${listening_service}-01-${name}", + target => $::haproxy::config_file, content => template('haproxy/haproxy_balancermember.erb'), } } diff --git a/haproxy/manifests/balancermember/collect_exported.pp b/haproxy/manifests/balancermember/collect_exported.pp new file mode 100644 index 000000000..f32696e47 --- /dev/null +++ b/haproxy/manifests/balancermember/collect_exported.pp @@ -0,0 +1,8 @@ +# Private define +define haproxy::balancermember::collect_exported { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + Haproxy::Balancermember <<| listening_service == $name |>> +} diff --git a/haproxy/manifests/config.pp b/haproxy/manifests/config.pp new file mode 100644 index 000000000..5975e3086 --- /dev/null +++ b/haproxy/manifests/config.pp @@ -0,0 +1,34 @@ +# Private class +class haproxy::config inherits haproxy { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + concat { $config_file: + owner => '0', + group => '0', + mode => '0644', + } + + # Simple Header + concat::fragment { '00-header': + target => $config_file, + order => '01', + content => "# This file managed by Puppet\n", + } + + # Template uses $global_options, $defaults_options + concat::fragment { 'haproxy-base': + target => $config_file, + order => '10', + content => template('haproxy/haproxy-base.cfg.erb'), + } + + if $haproxy::global_options['chroot'] { + file { $haproxy::global_options['chroot']: + ensure => directory, + owner => $haproxy::global_options['user'], + group => $haproxy::global_options['group'], + } + } +} diff --git a/haproxy/manifests/frontend.pp b/haproxy/manifests/frontend.pp index 488acaf0f..5943f5889 100644 --- a/haproxy/manifests/frontend.pp +++ b/haproxy/manifests/frontend.pp @@ -5,44 +5,54 @@ # # === Requirement/Dependencies: # -# Currently requires the ripienaar/concat module on the Puppet Forge and +# Currently requires the puppetlabs/concat module on the Puppet Forge and # uses storeconfigs on the Puppet Master to export/collect resources # from all balancer members. # # === Parameters # # [*name*] -# The namevar of the defined resource type is the frontend service's name. -# This name goes right after the 'frontend' statement in haproxy.cfg +# The namevar of the defined resource type is the frontend service's name. +# This name goes right after the 'frontend' statement in haproxy.cfg # # [*ports*] -# Ports on which the proxy will listen for connections on the ip address +# Ports on which the proxy will listen for connections on the ip address # specified in the ipaddress parameter. Accepts either a single # comma-separated string or an array of strings which may be ports or # hyphenated port ranges. # +# [*bind*] +# Set of ip addresses, port and bind options +# $bind = { '10.0.0.1:80' => ['ssl', 'crt', '/path/to/my/crt.pem'] } +# # [*ipaddress*] -# The ip address the proxy binds to. Empty addresses, '*', and '0.0.0.0' -# mean that the proxy listens to all valid addresses on the system. +# The ip address the proxy binds to. +# Empty addresses, '*', and '0.0.0.0' mean that the proxy listens +# to all valid addresses on the system. # # [*mode*] -# The mode of operation for the frontend service. Valid values are undef, +# The mode of operation for the frontend service. Valid values are undef, # 'tcp', 'http', and 'health'. # +# [*bind_options*] +# (Deprecated) An array of options to be specified after the bind declaration +# in the listening serivce's configuration block. +# # [*options*] -# A hash of options that are inserted into the frontend service -# configuration block. +# A hash of options that are inserted into the frontend service +# configuration block. # # === Examples # # Exporting the resource for a balancer member: # # haproxy::frontend { 'puppet00': -# ipaddress => $::ipaddress, -# ports => '18140', -# mode => 'tcp', -# options => { -# 'option' => [ +# ipaddress => $::ipaddress, +# ports => '18140', +# mode => 'tcp', +# bind_options => 'accept-proxy', +# options => { +# 'option' => [ # 'tcplog', # 'accept-invalid-http-request', # ], @@ -56,21 +66,36 @@ # Gary Larizza # define haproxy::frontend ( - $ports, - $ipaddress = [$::ipaddress], + $ports = undef, + $ipaddress = undef, + $bind = undef, $mode = undef, $collect_exported = true, $options = { 'option' => [ 'tcplog', ], - } + }, + # Deprecated + $bind_options = '', ) { + + if $ports and $bind { + fail('The use of $ports and $bind is mutually exclusive, please choose either one') + } + if $ipaddress and $bind { + fail('The use of $ipaddress and $bind is mutually exclusive, please choose either one') + } + if $bind_options { + warning('The $bind_options parameter is deprecated; please use $bind instead') + } + if $bind { + validate_hash($bind) + } # Template uses: $name, $ipaddress, $ports, $options concat::fragment { "${name}_frontend_block": order => "15-${name}-00", - target => '/etc/haproxy/haproxy.cfg', + target => $::haproxy::config_file, content => template('haproxy/haproxy_frontend_block.erb'), } - } diff --git a/haproxy/manifests/init.pp b/haproxy/manifests/init.pp index 8fb60d7e9..3c4c261b6 100644 --- a/haproxy/manifests/init.pp +++ b/haproxy/manifests/init.pp @@ -5,15 +5,24 @@ # # === Requirement/Dependencies: # -# Currently requires the ripienaar/concat module on the Puppet Forge and +# Currently requires the puppetlabs/concat module on the Puppet Forge and # uses storeconfigs on the Puppet Master to export/collect resources # from all balancer members. # # === Parameters # -# [*enable*] -# Chooses whether haproxy should be installed or ensured absent. -# Currently ONLY accepts valid boolean true/false values. +# [*package_ensure*] +# Chooses whether the haproxy package should be installed or uninstalled. Defaults to 'present' +# +# [*package_name*] +# The package name of haproxy. Defaults to 'haproxy' +# +# [*service_ensure*] +# Chooses whether the haproxy service should be running & enabled at boot, or +# stopped and disabled at boot. Defaults to 'running' +# +# [*service_manage*] +# Chooses whether the haproxy service state should be managed by puppet at all. Defaults to true # # [*global_options*] # A hash of all the haproxy global options. If you want to specify more @@ -27,11 +36,21 @@ # options as an array and you will get a line for each of them in the # resultant haproxy.cfg file. # +#[*restart_command*] +# Command to use when restarting the on config changes. +# Passed directly as the 'restart' parameter to the service resource. +# Defaults to undef i.e. whatever the service default is. +# +#[*custom_fragment*] +# Allows arbitrary HAProxy configuration to be passed through to support +# additional configuration not available via parameters, or to short-circute +# the defined resources such as haproxy::listen when an operater would rather +# just write plain configuration. Accepts a string (ie, output from the +# template() function). Defaults to undef # # === Examples # # class { 'haproxy': -# enable => true, # global_options => { # 'log' => "${::ipaddress} local0", # 'chroot' => '/var/lib/haproxy', @@ -60,91 +79,63 @@ # } # class haproxy ( - $manage_service = true, - $enable = true, + $package_ensure = 'present', + $package_name = $haproxy::params::package_name, + $service_ensure = 'running', + $service_manage = true, $global_options = $haproxy::params::global_options, - $defaults_options = $haproxy::params::defaults_options -) inherits haproxy::params { - include concat::setup - - package { 'haproxy': - ensure => $enable ? { - true => present, - false => absent, - }, - name => 'haproxy', - } - - if $enable { - concat { '/etc/haproxy/haproxy.cfg': - owner => '0', - group => '0', - mode => '0644', - require => Package['haproxy'], - notify => $manage_service ? { - true => Service['haproxy'], - false => undef, - }, - } - - # Simple Header - concat::fragment { '00-header': - target => '/etc/haproxy/haproxy.cfg', - order => '01', - content => "# This file managed by Puppet\n", - } - - # Template uses $global_options, $defaults_options - concat::fragment { 'haproxy-base': - target => '/etc/haproxy/haproxy.cfg', - order => '10', - content => template('haproxy/haproxy-base.cfg.erb'), - } + $defaults_options = $haproxy::params::defaults_options, + $restart_command = undef, + $custom_fragment = undef, + $config_file = $haproxy::params::config_file, - if ($::osfamily == 'Debian') { - file { '/etc/default/haproxy': - content => 'ENABLED=1', - require => Package['haproxy'], - before => $manage_service ? { - true => Service['haproxy'], - false => undef, - }, - } - } + # Deprecated + $manage_service = undef, + $enable = undef, +) inherits haproxy::params { - if $global_options['chroot'] { - file { $global_options['chroot']: - ensure => directory, - } + if $service_ensure != true and $service_ensure != false { + if ! ($service_ensure in [ 'running','stopped']) { + fail('service_ensure parameter must be running, stopped, true, or false') } - } + validate_string($package_name,$package_ensure) + validate_bool($service_manage) - if $manage_service { - if $global_options['chroot'] { - $deps = [ - Concat['/etc/haproxy/haproxy.cfg'], - File[$global_options['chroot']], - ] + # To support deprecating $enable + if $enable != undef { + warning('The $enable parameter is deprecated; please use service_ensure and/or package_ensure instead') + if $enable { + $_package_ensure = 'present' + $_service_ensure = 'running' } else { - $deps = [ - Concat['/etc/haproxy/haproxy.cfg'], - ] + $_package_ensure = 'absent' + $_service_ensure = 'stopped' } + } else { + $_package_ensure = $package_ensure + $_service_ensure = $service_ensure + } - service { 'haproxy': - ensure => $enable ? { - true => running, - false => stopped, - }, - enable => $enable ? { - true => true, - false => false, - }, - name => 'haproxy', - hasrestart => true, - hasstatus => true, - require => $deps, - } + # To support deprecating $manage_service + if $manage_service != undef { + warning('The $manage_service parameter is deprecated; please use $service_manage instead') + $_service_manage = $manage_service + } else { + $_service_manage = $service_manage + } + + if $_package_ensure == 'absent' or $_package_ensure == 'purged' { + anchor { 'haproxy::begin': } + ~> class { 'haproxy::service': } + -> class { 'haproxy::config': } + -> class { 'haproxy::install': } + -> anchor { 'haproxy::end': } + } else { + anchor { 'haproxy::begin': } + -> class { 'haproxy::install': } + -> class { 'haproxy::config': } + ~> class { 'haproxy::service': } + -> anchor { 'haproxy::end': } } } diff --git a/haproxy/manifests/install.pp b/haproxy/manifests/install.pp new file mode 100644 index 000000000..4fbe90f79 --- /dev/null +++ b/haproxy/manifests/install.pp @@ -0,0 +1,11 @@ +# Private class +class haproxy::install inherits haproxy { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + package { $haproxy::package_name: + ensure => $haproxy::_package_ensure, + alias => 'haproxy', + } +} diff --git a/haproxy/manifests/listen.pp b/haproxy/manifests/listen.pp index 5e2fc762f..58ca23f1a 100644 --- a/haproxy/manifests/listen.pp +++ b/haproxy/manifests/listen.pp @@ -10,42 +10,50 @@ # # === Requirement/Dependencies: # -# Currently requires the ripienaar/concat module on the Puppet Forge and +# Currently requires the puppetlabs/concat module on the Puppet Forge and # uses storeconfigs on the Puppet Master to export/collect resources # from all balancer members. # # === Parameters # # [*name*] -# The namevar of the defined resource type is the listening service's name. -# This name goes right after the 'listen' statement in haproxy.cfg +# The namevar of the defined resource type is the listening service's name. +# This name goes right after the 'listen' statement in haproxy.cfg # # [*ports*] -# Ports on which the proxy will listen for connections on the ip address +# Ports on which the proxy will listen for connections on the ip address # specified in the ipaddress parameter. Accepts either a single # comma-separated string or an array of strings which may be ports or # hyphenated port ranges. # # [*ipaddress*] -# The ip address the proxy binds to. Empty addresses, '*', and '0.0.0.0' -# mean that the proxy listens to all valid addresses on the system. +# The ip address the proxy binds to. +# Empty addresses, '*', and '0.0.0.0' mean that the proxy listens +# to all valid addresses on the system. +# +# [*bind*] +# Set of ip addresses, port and bind options +# $bind = { '10.0.0.1:80' => ['ssl', 'crt', '/path/to/my/crt.pem'] } # # [*mode*] -# The mode of operation for the listening service. Valid values are undef, +# The mode of operation for the listening service. Valid values are undef, # 'tcp', 'http', and 'health'. # # [*options*] -# A hash of options that are inserted into the listening service -# configuration block. +# A hash of options that are inserted into the listening service +# configuration block. +# +# [*bind_options*] +# (Deprecated) An array of options to be specified after the bind declaration +# in the listening serivce's configuration block. # # [*collect_exported*] -# Boolean, default 'true'. True means 'collect exported @@balancermember resources' +# Boolean, default 'true'. True means 'collect exported @@balancermember resources' # (for the case when every balancermember node exports itself), false means -# 'rely on the existing declared balancermember resources' (for the case when you -# know the full set of balancermembers in advance and use haproxy::balancermember +# 'rely on the existing declared balancermember resources' (for the case when you +# know the full set of balancermembers in advance and use haproxy::balancermember # with array arguments, which allows you to deploy everything in 1 run) # -# # === Examples # # Exporting the resource for a balancer member: @@ -68,27 +76,48 @@ # Gary Larizza # define haproxy::listen ( - $ports, - $ipaddress = [$::ipaddress], - $mode = undef, - $collect_exported = true, - $options = { + $ports = undef, + $ipaddress = undef, + $bind = undef, + $mode = undef, + $collect_exported = true, + $options = { 'option' => [ 'tcplog', 'ssl-hello-chk' ], 'balance' => 'roundrobin' - } + }, + # Deprecated + $bind_options = '', ) { + + if $ports and $bind { + fail('The use of $ports and $bind is mutually exclusive, please choose either one') + } + if $ipaddress and $bind { + fail('The use of $ipaddress and $bind is mutually exclusive, please choose either one') + } + if $bind_options { + warning('The $bind_options parameter is deprecated; please use $bind instead') + } + if $bind { + validate_hash($bind) + } + + if defined(Haproxy::Backend[$name]) { + fail("An haproxy::backend resource was discovered with the same name (${name}) which is not supported") + } + # Template uses: $name, $ipaddress, $ports, $options concat::fragment { "${name}_listen_block": order => "20-${name}-00", - target => '/etc/haproxy/haproxy.cfg', + target => $::haproxy::config_file, content => template('haproxy/haproxy_listen_block.erb'), } if $collect_exported { - Haproxy::Balancermember <<| listening_service == $name |>> + haproxy::balancermember::collect_exported { $name: } } # else: the resources have been created and they introduced their # concat fragments. We don't have to do anything about them. diff --git a/haproxy/manifests/params.pp b/haproxy/manifests/params.pp index 53442ddcc..7ac6458d9 100644 --- a/haproxy/manifests/params.pp +++ b/haproxy/manifests/params.pp @@ -5,8 +5,9 @@ # extended by changing package names and configuration file paths. # class haproxy::params { - case $osfamily { - Redhat: { + case $::osfamily { + 'Archlinux', 'Debian', 'RedHat': { + $package_name = 'haproxy' $global_options = { 'log' => "${::ipaddress} local0", 'chroot' => '/var/lib/haproxy', @@ -32,34 +33,36 @@ ], 'maxconn' => '8000' } + $config_file = '/etc/haproxy/haproxy.cfg' } - Debian: { + 'FreeBSD': { + $package_name = 'haproxy' $global_options = { - 'log' => "${::ipaddress} local0", - 'chroot' => '/var/lib/haproxy', + 'log' => [ + '127.0.0.1 local0', + '127.0.0.1 local1 notice', + ], + 'chroot' => '/usr/local/haproxy', 'pidfile' => '/var/run/haproxy.pid', - 'maxconn' => '4000', - 'user' => 'haproxy', - 'group' => 'haproxy', + 'maxconn' => '4096', 'daemon' => '', - 'stats' => 'socket /var/lib/haproxy/stats' } $defaults_options = { - 'log' => 'global', - 'stats' => 'enable', - 'option' => 'redispatch', - 'retries' => '3', - 'timeout' => [ - 'http-request 10s', - 'queue 1m', - 'connect 10s', - 'client 1m', - 'server 1m', - 'check 10s', + 'log' => 'global', + 'mode' => 'http', + 'option' => [ + 'httplog', + 'dontlognull', ], - 'maxconn' => '8000' + 'retries' => '3', + 'redispatch' => '', + 'maxconn' => '2000', + 'contimeout' => '5000', + 'clitimeout' => '50000', + 'srvtimeout' => '50000', } + $config_file = '/usr/local/etc/haproxy.conf' } - default: { fail("The $::osfamily operating system is not supported with the haproxy module") } + default: { fail("The ${::osfamily} operating system is not supported with the haproxy module") } } } diff --git a/haproxy/manifests/peer.pp b/haproxy/manifests/peer.pp new file mode 100644 index 000000000..6cb36bfee --- /dev/null +++ b/haproxy/manifests/peer.pp @@ -0,0 +1,16 @@ +define haproxy::peer ( + $peers_name, + $port, + $ensure = 'present', + $server_names = $::hostname, + $ipaddresses = $::ipaddress, +) { + + # Templats uses $ipaddresses, $server_name, $ports, $option + concat::fragment { "peers-${peers_name}-${name}": + order => "30-peers-01-${peers_name}-${name}", + ensure => $ensure, + target => '/etc/haproxy/haproxy.cfg', + content => template('haproxy/haproxy_peer.erb'), + } +} diff --git a/haproxy/manifests/peer/collect_exported.pp b/haproxy/manifests/peer/collect_exported.pp new file mode 100644 index 000000000..3d16a6428 --- /dev/null +++ b/haproxy/manifests/peer/collect_exported.pp @@ -0,0 +1,8 @@ +# Private define +define haproxy::peer::collect_exported { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + Haproxy::Peer <<| peers_name == $name |>> +} diff --git a/haproxy/manifests/peers.pp b/haproxy/manifests/peers.pp new file mode 100644 index 000000000..666f4dad0 --- /dev/null +++ b/haproxy/manifests/peers.pp @@ -0,0 +1,17 @@ +define haproxy::peers ( + $collect_exported = true, +) { + + # Template uses: $name, $ipaddress, $ports, $options + concat::fragment { "${name}_peers_block": + order => "30-peers-00-${name}", + target => '/etc/haproxy/haproxy.cfg', + content => template('haproxy/haproxy_peers_block.erb'), + } + + if $collect_exported { + haproxy::peer::collect_exported { $name: } + } + # else: the resources have been created and they introduced their + # concat fragments. We don't have to do anything about them. +} diff --git a/haproxy/manifests/service.pp b/haproxy/manifests/service.pp new file mode 100644 index 000000000..691aa137e --- /dev/null +++ b/haproxy/manifests/service.pp @@ -0,0 +1,28 @@ +# Private class +class haproxy::service inherits haproxy { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + if $haproxy::_service_manage { + if ($::osfamily == 'Debian') { + file { '/etc/default/haproxy': + content => 'ENABLED=1', + before => Service['haproxy'], + } + } + + service { 'haproxy': + ensure => $haproxy::_service_ensure, + enable => $haproxy::_service_ensure ? { + 'running' => true, + 'stopped' => false, + default => $haproxy::_service_ensure, + }, + name => 'haproxy', + hasrestart => true, + hasstatus => true, + restart => $haproxy::restart_command, + } + } +} diff --git a/haproxy/manifests/userlist.pp b/haproxy/manifests/userlist.pp new file mode 100644 index 000000000..60c5ede20 --- /dev/null +++ b/haproxy/manifests/userlist.pp @@ -0,0 +1,41 @@ +# == Define Resource Type: haproxy::userlist +# +# This type will set up a userlist configuration block inside the haproxy.cfg +# file on an haproxy load balancer. +# +# See http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4 for more info +# +# === Requirement/Dependencies: +# +# Currently requires the puppetlabs/concat module on the Puppet Forge +# +# === Parameters +# +# [*name*] +# The namevar of the define resource type is the userlist name. +# This name goes right after the 'userlist' statement in haproxy.cfg +# +# [*users*] +# An array of users in the userlist. +# See http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4-user +# +# [*groups*] +# An array of groups in the userlist. +# See http://cbonte.github.io/haproxy-dconv/configuration-1.4.html#3.4-group +# +# === Authors +# +# Jeremy Kitchen +# +define haproxy::userlist ( + $users = undef, + $groups = undef, +) { + + # Template usse $name, $users, $groups + concat::fragment { "${name}_userlist_block": + order => "12-${name}-00", + target => $::haproxy::config_file, + content => template('haproxy/haproxy_userlist_block.erb'), + } +} diff --git a/haproxy/metadata.json b/haproxy/metadata.json new file mode 100644 index 000000000..a45e48482 --- /dev/null +++ b/haproxy/metadata.json @@ -0,0 +1,73 @@ +{ + "name": "puppetlabs-haproxy", + "version": "1.1.0", + "author": "Puppet Labs", + "summary": "Configures HAProxy servers and manages the configuration of backend member servers.", + "license": "Apache-2.0", + "source": "https://github.com/puppetlabs/puppetlabs-haproxy", + "project_page": "https://github.com/puppetlabs/puppetlabs-haproxy", + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "5", + "6", + "7" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "10.04", + "12.04", + "14.04" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": "3.x" + }, + { + "name": "puppet", + "version_requirement": "3.x" + } + ], + "dependencies": [ + {"name":"puppetlabs/stdlib","version_requirement":">= 2.4.0"}, + {"name":"puppetlabs/concat","version_requirement":">= 1.1.0"} + ] +} diff --git a/haproxy/spec/acceptance/basic_spec.rb b/haproxy/spec/acceptance/basic_spec.rb new file mode 100644 index 000000000..c16d9002b --- /dev/null +++ b/haproxy/spec/acceptance/basic_spec.rb @@ -0,0 +1,93 @@ +require 'spec_helper_acceptance' + +# C9708 C9709 WONTFIX +describe "configuring haproxy", :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + # C9961 + describe 'not managing the service' do + it 'should not listen on any ports' do + pp = <<-EOS + class { 'haproxy': + service_manage => false, + } + haproxy::listen { 'stats': + ipaddress => '127.0.0.1', + ports => ['9090','9091'], + options => { + 'mode' => 'http', + 'stats' => ['uri /','auth puppet:puppet'], + }, + } + haproxy::listen { 'test00': ports => '80',} + EOS + apply_manifest(pp, :catch_failures => true) + end + + describe port('9090') do + it { should_not be_listening } + end + describe port('9091') do + it { should_not be_listening } + end + end + + describe "configuring haproxy load balancing" do + before :all do + end + + describe "multiple ports" do + it 'should be able to listen on an array of ports' do + pp = <<-EOS + class { 'haproxy': } + haproxy::listen { 'stats': + ipaddress => '127.0.0.1', + ports => ['9090','9091'], + mode => 'http', + options => { 'stats' => ['uri /','auth puppet:puppet'], }, + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it 'should have stats listening on each port' do + ['9090','9091'].each do |port| + shell("/usr/bin/curl -u puppet:puppet localhost:#{port}") do |r| + r.stdout.should =~ /HAProxy/ + r.exit_code.should == 0 + end + end + end + end + end + + # C9934 + describe "uninstalling haproxy" do + it 'removes it' do + pp = <<-EOS + class { 'haproxy': + package_ensure => 'absent', + service_ensure => 'stopped', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + describe package('haproxy') do + it { should_not be_installed } + end + end + + # C9935 C9939 + describe "disabling haproxy" do + it 'stops the service' do + pp = <<-EOS + class { 'haproxy': + service_ensure => 'stopped', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + describe service('haproxy') do + it { should_not be_running } + it { should_not be_enabled } + end + end +end diff --git a/haproxy/spec/acceptance/frontbackend_spec.rb b/haproxy/spec/acceptance/frontbackend_spec.rb new file mode 100644 index 000000000..76c4d1613 --- /dev/null +++ b/haproxy/spec/acceptance/frontbackend_spec.rb @@ -0,0 +1,80 @@ +require 'spec_helper_acceptance' + +describe "frontend backend defines", :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + it 'should be able to configure the frontend/backend with puppet' do + pp = <<-EOS + class { 'haproxy': } + haproxy::frontend { 'app00': + ipaddress => $::ipaddress_lo, + mode => 'http', + ports => '5555', + options => { 'default_backend' => 'app00' }, + } + haproxy::backend { 'app00': + collect_exported => false, + options => { 'mode' => 'http' }, + } + haproxy::balancermember { 'port 5556': + listening_service => 'app00', + ports => '5556', + } + haproxy::balancermember { 'port 5557': + listening_service => 'app00', + ports => '5557', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + # This is not great since it depends on the ordering served by the load + # balancer. Something with retries would be better. + # C9945 + it "should do a curl against the LB to make sure it gets a response from each port" do + shell('curl localhost:5555').stdout.chomp.should match(/Response on 555(6|7)/) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 555(6|7)/) + end + + it 'should be able to configure the frontend/backend with one node up' do + pp = <<-EOS + class { 'haproxy': } + haproxy::frontend { 'app00': + ipaddress => $::ipaddress_lo, + mode => 'http', + ports => '5555', + options => { 'default_backend' => 'app00' }, + } + haproxy::backend { 'app00': + collect_exported => false, + options => { 'mode' => 'http' }, + } + haproxy::balancermember { 'port 5556': + listening_service => 'app00', + ports => '5556', + } + haproxy::balancermember { 'port 5557': + listening_service => 'app00', + ports => '5558', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + # C9951 + it "should do a curl against the LB to make sure it gets a response from each port" do + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + end + + it 'having no address set but setting bind' do + pp = <<-EOS + class { 'haproxy': } + haproxy::frontend { 'app0': + bind => + { '127.0.0.1:5555' => [] } + , + } + EOS + apply_manifest(pp, :catch_failures => true) + end + +end diff --git a/haproxy/spec/acceptance/listen_spec.rb b/haproxy/spec/acceptance/listen_spec.rb new file mode 100644 index 000000000..eb2bff5a9 --- /dev/null +++ b/haproxy/spec/acceptance/listen_spec.rb @@ -0,0 +1,103 @@ +require 'spec_helper_acceptance' + +describe "listen define", :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + it 'should be able to configure the listen with puppet' do + pp = <<-EOS + class { 'haproxy': } + haproxy::listen { 'app00': + ipaddress => $::ipaddress_lo, + ports => '5555', + mode => 'http', + } + haproxy::balancermember { 'port 5556': + listening_service => 'app00', + ports => '5556', + } + haproxy::balancermember { 'port 5557': + listening_service => 'app00', + ports => '5557', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + # This is not great since it depends on the ordering served by the load + # balancer. Something with retries would be better. + # C9876 C9877 C9941 C9954 + it "should do a curl against the LB to make sure it gets a response from each port" do + shell('curl localhost:5555').stdout.chomp.should match(/Response on 555(6|7)/) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 555(6|7)/) + end + + # C9955 + it 'should be able to configure the listen active/passive' do + pp = <<-EOS + class { 'haproxy': } + haproxy::listen { 'app00': + ipaddress => $::ipaddress_lo, + ports => '5555', + mode => 'http', + options => { 'option' => 'httpchk', }, + } + haproxy::balancermember { 'port 5556': + listening_service => 'app00', + ports => '5556', + options => 'check', + } + haproxy::balancermember { 'port 5557': + listening_service => 'app00', + ports => '5557', + options => ['check','backup'], + } + EOS + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it "should do a curl against the LB to make sure it only gets a response from the active port" do + sleep(10) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + end + + # C9942 C9944 WONTFIX + + # C9943 + it 'should be able to configure the listen with only one node up' do + pp = <<-EOS + class { 'haproxy': } + haproxy::listen { 'app00': + ipaddress => $::ipaddress_lo, + ports => '5555', + mode => 'http', + } + haproxy::balancermember { 'port 5556': + listening_service => 'app00', + ports => '5556', + } + haproxy::balancermember { 'port 5557': + listening_service => 'app00', + ports => '5558', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + it "should do a curl against the LB to make sure it gets a response from each port" do + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + shell('curl localhost:5555').stdout.chomp.should match(/Response on 5556/) + end + + it 'having no address set but setting bind' do + pp = <<-EOS + class { 'haproxy': } + haproxy::listen { 'app0': + bind => + { '127.0.0.1:5555' => [] } + , + } + EOS + apply_manifest(pp, :catch_failures => true) + end + +end diff --git a/haproxy/spec/acceptance/nodesets/centos-5-vcloud.yml b/haproxy/spec/acceptance/nodesets/centos-5-vcloud.yml new file mode 100644 index 000000000..377d0eec5 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-5-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'centos-5-vcloud': + roles: + - master + platform: el-5-x86_64 + hypervisor: vcloud + template: centos-5-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/centos-59-x64.yml b/haproxy/spec/acceptance/nodesets/centos-59-x64.yml new file mode 100644 index 000000000..2ad90b86a --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-59-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-59-x64: + roles: + - master + platform: el-5-x86_64 + box : centos-59-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: git diff --git a/haproxy/spec/acceptance/nodesets/centos-6-vcloud.yml b/haproxy/spec/acceptance/nodesets/centos-6-vcloud.yml new file mode 100644 index 000000000..ca9c1d329 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-6-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'centos-6-vcloud': + roles: + - master + platform: el-6-x86_64 + hypervisor: vcloud + template: centos-6-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/centos-64-x64-pe.yml b/haproxy/spec/acceptance/nodesets/centos-64-x64-pe.yml new file mode 100644 index 000000000..7d9242f1b --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-64-x64-pe.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-64-x64: + roles: + - master + - database + - dashboard + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: pe diff --git a/haproxy/spec/acceptance/nodesets/centos-64-x64.yml b/haproxy/spec/acceptance/nodesets/centos-64-x64.yml new file mode 100644 index 000000000..0385e951d --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-64-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - default + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/haproxy/spec/acceptance/nodesets/centos-65-x64.yml b/haproxy/spec/acceptance/nodesets/centos-65-x64.yml new file mode 100644 index 000000000..4e2cb809e --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/centos-65-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-65-x64: + roles: + - master + platform: el-6-x86_64 + box : centos-65-x64-vbox436-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/haproxy/spec/acceptance/nodesets/debian-6-vcloud.yml b/haproxy/spec/acceptance/nodesets/debian-6-vcloud.yml new file mode 100644 index 000000000..658c7d4c0 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/debian-6-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'debian-6-amd64': + roles: + - master + platform: debian-6-amd64 + hypervisor: vcloud + template: debian-6-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/debian-7-vcloud.yml b/haproxy/spec/acceptance/nodesets/debian-7-vcloud.yml new file mode 100644 index 000000000..9323473e3 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/debian-7-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'debian-7-amd64': + roles: + - master + platform: debian-7-amd64 + hypervisor: vcloud + template: debian-7-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/default.yml b/haproxy/spec/acceptance/nodesets/default.yml new file mode 100644 index 000000000..0385e951d --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-64-x64: + roles: + - default + platform: el-6-x86_64 + box : centos-64-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/haproxy/spec/acceptance/nodesets/redhat-7-vcloud.yml b/haproxy/spec/acceptance/nodesets/redhat-7-vcloud.yml new file mode 100644 index 000000000..cf8f79a97 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/redhat-7-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'redhat-7-vcloud': + roles: + - master + platform: el-7-x86_64 + hypervisor: vcloud + template: redhat-7-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/ubuntu-1004-x86_64-vcloud.yml b/haproxy/spec/acceptance/nodesets/ubuntu-1004-x86_64-vcloud.yml new file mode 100644 index 000000000..19a918f54 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/ubuntu-1004-x86_64-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'ubuntu-1004-amd64': + roles: + - master + platform: ubuntu-10.04-amd64 + hypervisor: vcloud + template: ubuntu-1004-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/ubuntu-1404-x86_64-vcloud.yml b/haproxy/spec/acceptance/nodesets/ubuntu-1404-x86_64-vcloud.yml new file mode 100644 index 000000000..d84b18e50 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/ubuntu-1404-x86_64-vcloud.yml @@ -0,0 +1,15 @@ +HOSTS: + 'ubuntu-1404-amd64': + roles: + - master + platform: ubuntu-14.04-amd64 + hypervisor: vcloud + template: ubuntu-1404-x86_64 +CONFIG: + type: foss + ssh: + keys: "~/.ssh/id_rsa-acceptance" + datastore: instance0 + folder: Delivery/Quality Assurance/Enterprise/Dynamic + resourcepool: delivery/Quality Assurance/Enterprise/Dynamic + pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/haproxy/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/haproxy/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml new file mode 100644 index 000000000..5ca1514e4 --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-10044-x64: + roles: + - master + platform: ubuntu-10.04-amd64 + box : ubuntu-server-10044-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/haproxy/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/haproxy/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml new file mode 100644 index 000000000..d065b304f --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-server-12042-x64: + roles: + - master + platform: ubuntu-12.04-amd64 + box : ubuntu-server-12042-x64-vbox4210-nocm + box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box + hypervisor : vagrant +CONFIG: + type: foss diff --git a/haproxy/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/haproxy/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 000000000..cba1cd04c --- /dev/null +++ b/haproxy/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,11 @@ +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-14.04-amd64 + box : puppetlabs/ubuntu-14.04-64-nocm + box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm + hypervisor : vagrant +CONFIG: + log_level : debug + type: git diff --git a/haproxy/spec/acceptance/unsupported_spec.rb b/haproxy/spec/acceptance/unsupported_spec.rb new file mode 100644 index 000000000..684f587c1 --- /dev/null +++ b/haproxy/spec/acceptance/unsupported_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper_acceptance' + +# C9710 C9711 +describe 'unsupported distributions and OSes', :if => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + it 'should fail' do + pp = <<-EOS + class { 'haproxy': } + EOS + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/not supported/i) + end +end diff --git a/haproxy/spec/acceptance/userlist_spec.rb b/haproxy/spec/acceptance/userlist_spec.rb new file mode 100644 index 000000000..d03a6a242 --- /dev/null +++ b/haproxy/spec/acceptance/userlist_spec.rb @@ -0,0 +1,78 @@ +require 'spec_helper_acceptance' + +# lucid ships with haproxy 1.3 which does not have userlist support by default +describe "userlist define", :unless => (UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) or (fact('lsbdistcodename') == 'lucid') or (fact('osfamily') == 'RedHat' and fact('operatingsystemmajrelease') == '5')) do + it 'should be able to configure the listen with puppet' do + # C9966 C9970 + pp = <<-EOS + class { 'haproxy': } + haproxy::userlist { 'users_groups': + users => [ + 'test1 insecure-password elgato', + 'test2 insecure-password elgato', + '', + ], + groups => [ + 'g1 users test1', + '', + ] + } + + haproxy::listen { 'app00': + collect_exported => false, + ipaddress => $::ipaddress_lo, + ports => '5555', + options => { + 'mode' => 'http', + 'acl' => 'auth_ok http_auth(users_groups)', + 'http-request' => 'auth realm Okay if !auth_ok', + }, + } + haproxy::balancermember { 'app00 port 5556': + listening_service => 'app00', + ports => '5556', + } + + haproxy::listen { 'app01': + collect_exported => false, + ipaddress => $::ipaddress_lo, + ports => '5554', + options => { + 'mode' => 'http', + 'acl' => 'auth_ok http_auth_group(users_groups) g1', + 'http-request' => 'auth realm Okay if !auth_ok', + }, + } + haproxy::balancermember { 'app01 port 5556': + listening_service => 'app01', + ports => '5556', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + # C9957 + it "test1 should auth as user" do + shell('curl http://test1:elgato@localhost:5555').stdout.chomp.should eq('Response on 5556') + end + it "test2 should auth as user" do + shell('curl http://test2:elgato@localhost:5555').stdout.chomp.should eq('Response on 5556') + end + + # C9958 + it "should not auth as user" do + shell('curl http://test3:elgato@localhost:5555').stdout.chomp.should_not eq('Response on 5556') + end + + # C9959 + it "should auth as group" do + shell('curl http://test1:elgato@localhost:5554').stdout.chomp.should eq('Response on 5556') + end + + # C9960 + it "should not auth as group" do + shell('curl http://test2:elgato@localhost:5554').stdout.chomp.should_not eq('Response on 5556') + end + + # C9965 C9967 C9968 C9969 WONTFIX +end diff --git a/haproxy/spec/classes/haproxy_spec.rb b/haproxy/spec/classes/haproxy_spec.rb index 4b5902ce5..0b8f1a884 100644 --- a/haproxy/spec/classes/haproxy_spec.rb +++ b/haproxy/spec/classes/haproxy_spec.rb @@ -9,15 +9,18 @@ end context 'on supported platforms' do describe 'for OS-agnostic configuration' do - ['Debian', 'RedHat'].each do |osfamily| + ['Debian', 'RedHat', 'Archlinux', 'FreeBSD',].each do |osfamily| context "on #{osfamily} family operatingsystems" do let(:facts) do { :osfamily => osfamily }.merge default_facts end let(:params) do - {'enable' => true} + { + 'service_ensure' => 'running', + 'package_ensure' => 'present', + 'service_manage' => true + } end - it { should include_class('concat::setup') } it 'should install the haproxy package' do subject.should contain_package('haproxy').with( 'ensure' => 'present' @@ -28,13 +31,33 @@ 'ensure' => 'running', 'enable' => 'true', 'hasrestart' => 'true', - 'hasstatus' => 'true', - 'require' => [ - 'Concat[/etc/haproxy/haproxy.cfg]', - 'File[/var/lib/haproxy]' - ] + 'hasstatus' => 'true' + ) + end + end + # C9938 + context "on #{osfamily} when specifying custom content" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end + let(:params) do + { 'custom_fragment' => "listen stats :9090\n mode http\n stats uri /\n stats auth puppet:puppet\n" } + end + it 'should set the haproxy package' do + subject.should contain_concat__fragment('haproxy-base').with_content( + /listen stats :9090\n mode http\n stats uri \/\n stats auth puppet:puppet\n/ ) end + end + end + end + + describe 'for linux operating systems' do + ['Debian', 'RedHat', 'Archlinux', ].each do |osfamily| + context "on #{osfamily} family operatingsystems" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end it 'should set up /etc/haproxy/haproxy.cfg as a concat resource' do subject.should contain_concat('/etc/haproxy/haproxy.cfg').with( 'owner' => '0', @@ -44,7 +67,9 @@ end it 'should manage the chroot directory' do subject.should contain_file('/var/lib/haproxy').with( - 'ensure' => 'directory' + 'ensure' => 'directory', + 'owner' => 'haproxy', + 'group' => 'haproxy' ) end it 'should contain a header concat fragment' do @@ -62,6 +87,7 @@ end describe 'Base concat fragment contents' do let(:contents) { param_value(subject, 'concat::fragment', 'haproxy-base', 'content').split("\n") } + # C9936 C9937 it 'should contain global and defaults sections' do contents.should include('global') contents.should include('defaults') @@ -89,32 +115,220 @@ end let(:params) do { - 'enable' => true, - 'manage_service' => false, + 'service_ensure' => true, + 'package_ensure' => 'present', + 'service_manage' => false } end - it { should include_class('concat::setup') } it 'should install the haproxy package' do subject.should contain_package('haproxy').with( 'ensure' => 'present' ) end - it 'should install the haproxy service' do + it 'should not manage the haproxy service' do subject.should_not contain_service('haproxy') end + it 'should set up /etc/haproxy/haproxy.cfg as a concat resource' do + subject.should contain_concat('/etc/haproxy/haproxy.cfg').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644' + ) + end + it 'should manage the chroot directory' do + subject.should contain_file('/var/lib/haproxy').with( + 'ensure' => 'directory' + ) + end + it 'should contain a header concat fragment' do + subject.should contain_concat__fragment('00-header').with( + 'target' => '/etc/haproxy/haproxy.cfg', + 'order' => '01', + 'content' => "# This file managed by Puppet\n" + ) + end + it 'should contain a haproxy-base concat fragment' do + subject.should contain_concat__fragment('haproxy-base').with( + 'target' => '/etc/haproxy/haproxy.cfg', + 'order' => '10' + ) + end + describe 'Base concat fragment contents' do + let(:contents) { param_value(subject, 'concat::fragment', 'haproxy-base', 'content').split("\n") } + it 'should contain global and defaults sections' do + contents.should include('global') + contents.should include('defaults') + end + it 'should log to an ip address for local0' do + contents.should be_any { |match| match =~ / log \d+(\.\d+){3} local0/ } + end + it 'should specify the default chroot' do + contents.should include(' chroot /var/lib/haproxy') + end + it 'should specify the correct user' do + contents.should include(' user haproxy') + end + it 'should specify the correct group' do + contents.should include(' group haproxy') + end + it 'should specify the correct pidfile' do + contents.should include(' pidfile /var/run/haproxy.pid') + end + end + end + context "on #{osfamily} when specifying a restart_command" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end + let(:params) do + { + 'restart_command' => '/etc/init.d/haproxy reload', + 'service_manage' => true + } + end + it 'should set the haproxy package' do + subject.should contain_service('haproxy').with( + 'restart' => '/etc/init.d/haproxy reload' + ) + end + end + end + end + + describe 'for freebsd' do + context "on freebsd family operatingsystems" do + let(:facts) do + { :osfamily => 'FreeBSD' }.merge default_facts + end + it 'should set up /usr/local/etc/haproxy.conf as a concat resource' do + subject.should contain_concat('/usr/local/etc/haproxy.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644' + ) + end + it 'should manage the chroot directory' do + subject.should contain_file('/usr/local/haproxy').with( + 'ensure' => 'directory' + ) + end + it 'should contain a header concat fragment' do + subject.should contain_concat__fragment('00-header').with( + 'target' => '/usr/local/etc/haproxy.conf', + 'order' => '01', + 'content' => "# This file managed by Puppet\n" + ) + end + it 'should contain a haproxy-base concat fragment' do + subject.should contain_concat__fragment('haproxy-base').with( + 'target' => '/usr/local/etc/haproxy.conf', + 'order' => '10' + ) + end + describe 'Base concat fragment contents' do + let(:contents) { param_value(subject, 'concat::fragment', 'haproxy-base', 'content').split("\n") } + # C9936 C9937 + it 'should contain global and defaults sections' do + contents.should include('global') + contents.should include('defaults') + end + it 'should log to an ip address for local0' do + contents.should be_any { |match| match =~ / log \d+(\.\d+){3} local0/ } + end + it 'should specify the default chroot' do + contents.should include(' chroot /usr/local/haproxy') + end + it 'should specify the correct pidfile' do + contents.should include(' pidfile /var/run/haproxy.pid') + end + end + end + context "on freebsd family operatingsystems without managing the service" do + let(:facts) do + { :osfamily => 'FreeBSD' }.merge default_facts + end + let(:params) do + { + 'service_ensure' => true, + 'package_ensure' => 'present', + 'service_manage' => false + } + end + it 'should install the haproxy package' do + subject.should contain_package('haproxy').with( + 'ensure' => 'present' + ) + end + it 'should not manage the haproxy service' do + subject.should_not contain_service('haproxy') + end + it 'should set up /usr/local/etc/haproxy.conf as a concat resource' do + subject.should contain_concat('/usr/local/etc/haproxy.conf').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644' + ) + end + it 'should manage the chroot directory' do + subject.should contain_file('/usr/local/haproxy').with( + 'ensure' => 'directory' + ) + end + it 'should contain a header concat fragment' do + subject.should contain_concat__fragment('00-header').with( + 'target' => '/usr/local/etc/haproxy.conf', + 'order' => '01', + 'content' => "# This file managed by Puppet\n" + ) + end + it 'should contain a haproxy-base concat fragment' do + subject.should contain_concat__fragment('haproxy-base').with( + 'target' => '/usr/local/etc/haproxy.conf', + 'order' => '10' + ) + end + describe 'Base concat fragment contents' do + let(:contents) { param_value(subject, 'concat::fragment', 'haproxy-base', 'content').split("\n") } + it 'should contain global and defaults sections' do + contents.should include('global') + contents.should include('defaults') + end + it 'should log to an ip address for local0' do + contents.should be_any { |match| match =~ / log \d+(\.\d+){3} local0/ } + end + it 'should specify the default chroot' do + contents.should include(' chroot /usr/local/haproxy') + end + it 'should specify the correct pidfile' do + contents.should include(' pidfile /var/run/haproxy.pid') + end + end + end + context "on freebsd when specifying a restart_command" do + let(:facts) do + { :osfamily => 'FreeBSD' }.merge default_facts + end + let(:params) do + { + 'restart_command' => '/usr/local/etc/rc.d/haproxy reload', + 'service_manage' => true + } + end + it 'should set the haproxy package' do + subject.should contain_service('haproxy').with( + 'restart' => '/usr/local/etc/rc.d/haproxy reload' + ) end end end + describe 'for OS-specific configuration' do context 'only on Debian family operatingsystems' do let(:facts) do { :osfamily => 'Debian' }.merge default_facts end it 'should manage haproxy service defaults' do - subject.should contain_file('/etc/default/haproxy').with( - 'before' => 'Service[haproxy]', - 'require' => 'Package[haproxy]' - ) + subject.should contain_file('/etc/default/haproxy') verify_contents(subject, '/etc/default/haproxy', ['ENABLED=1']) end end @@ -125,9 +339,10 @@ end end end + context 'on unsupported operatingsystems' do let(:facts) do - { :osfamily => 'RainbowUnicorn' }.merge default_facts + { :osfamily => 'windows' }.merge default_facts end it do expect { diff --git a/haproxy/spec/defines/backend_spec.rb b/haproxy/spec/defines/backend_spec.rb index b672d7689..696cfdec3 100644 --- a/haproxy/spec/defines/backend_spec.rb +++ b/haproxy/spec/defines/backend_spec.rb @@ -1,15 +1,17 @@ require 'spec_helper' describe 'haproxy::backend' do - let(:title) { 'tyler' } - let(:facts) {{ :ipaddress => '1.1.1.1' }} + let(:pre_condition) { 'include haproxy' } + let(:facts) do + { + :ipaddress => '1.1.1.1', + :osfamily => 'Redhat', + :concat_basedir => '/dne', + } + end context "when no options are passed" do - let (:params) do - { - :name => 'bar' - } - end + let(:title) { 'bar' } it { should contain_concat__fragment('bar_backend_block').with( 'order' => '20-bar-00', @@ -18,8 +20,17 @@ ) } end + # C9953 + context "when a listen is created with the same name" do + let(:title) { 'apache' } + let(:pre_condition) do + "haproxy::listen { 'apache': ports => '443', }" + end + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /discovered with the same name/ + end + end + # C9956 WONTFIX end - - diff --git a/haproxy/spec/defines/balancermember_spec.rb b/haproxy/spec/defines/balancermember_spec.rb index 4da2815e2..fb7a22f91 100644 --- a/haproxy/spec/defines/balancermember_spec.rb +++ b/haproxy/spec/defines/balancermember_spec.rb @@ -1,11 +1,14 @@ require 'spec_helper' describe 'haproxy::balancermember' do + let(:pre_condition) { 'include haproxy' } let(:title) { 'tyler' } let(:facts) do { - :ipaddress => '1.1.1.1', - :hostname => 'dero' + :ipaddress => '1.1.1.1', + :hostname => 'dero', + :osfamily => 'Redhat', + :concat_basedir => '/dne', } end @@ -20,9 +23,9 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => " server dero 1.1.1.1:18140 check\n" + 'content' => " server dero 1.1.1.1:18140 check\n" ) } end @@ -37,10 +40,10 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', 'ensure' => 'absent', - 'content' => " server dero 1.1.1.1:18140 \n" + 'content' => " server dero 1.1.1.1:18140 \n" ) } end @@ -55,9 +58,9 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => " server dero 1.1.1.1:18140 check close\n" + 'content' => " server dero 1.1.1.1:18140 check close\n" ) } end @@ -73,7 +76,7 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', 'content' => " server dero 1.1.1.1:18140 cookie dero check close\n" ) } @@ -91,9 +94,9 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => " server server01 192.168.56.200:18140 check\n server server02 192.168.56.201:18140 check\n" + 'content' => " server server01 192.168.56.200:18140 check\n server server02 192.168.56.201:18140 check\n" ) } end context 'with multiple servers and multiple ports' do @@ -109,9 +112,26 @@ end it { should contain_concat__fragment('croy_balancermember_tyler').with( - 'order' => '20-croy-tyler', + 'order' => '20-croy-01-tyler', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => " server server01 192.168.56.200:18140,192.168.56.200:18150 check\n server server02 192.168.56.201:18140,192.168.56.201:18150 check\n" + 'content' => " server server01 192.168.56.200:18140 check\n server server01 192.168.56.200:18150 check\n server server02 192.168.56.201:18140 check\n server server02 192.168.56.201:18150 check\n" + ) } + end + context 'with multiple servers and no port' do + let(:params) do + { + :name => 'tyler', + :listening_service => 'croy', + :server_names => ['server01', 'server02'], + :ipaddresses => ['192.168.56.200', '192.168.56.201'], + :options => ['check'] + } + end + + it { should contain_concat__fragment('croy_balancermember_tyler').with( + 'order' => '20-croy-01-tyler', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " server server01 192.168.56.200 check\n server server02 192.168.56.201 check\n" ) } end end diff --git a/haproxy/spec/defines/frontend_spec.rb b/haproxy/spec/defines/frontend_spec.rb index 04acce86e..9906afbba 100644 --- a/haproxy/spec/defines/frontend_spec.rb +++ b/haproxy/spec/defines/frontend_spec.rb @@ -1,12 +1,20 @@ require 'spec_helper' describe 'haproxy::frontend' do + let(:pre_condition) { 'include haproxy' } let(:title) { 'tyler' } - let(:facts) {{ :ipaddress => '1.1.1.1' }} + let(:facts) do + { + :ipaddress => '1.1.1.1', + :osfamily => 'Redhat', + :concat_basedir => '/dne', + } + end context "when only one port is provided" do let(:params) do { :name => 'croy', + :ipaddress => '1.1.1.1', :ports => '18140' } end @@ -14,9 +22,10 @@ it { should contain_concat__fragment('croy_frontend_block').with( 'order' => '15-croy-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nfrontend croy\n bind 1.1.1.1:18140\n option tcplog\n" + 'content' => "\nfrontend croy\n bind 1.1.1.1:18140 \n option tcplog\n" ) } end + # C9948 C9947 context "when an array of ports is provided" do let(:params) do { @@ -32,7 +41,126 @@ it { should contain_concat__fragment('apache_frontend_block').with( 'order' => '15-apache-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nfrontend apache\n bind 23.23.23.23:80\n bind 23.23.23.23:443\n option tcplog\n" + 'content' => "\nfrontend apache\n bind 23.23.23.23:80 \n bind 23.23.23.23:443 \n option tcplog\n" + ) } + end + # C9948 + context "when a comma-separated list of ports is provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => '80,443' + } + end + + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind 23.23.23.23:80 \n bind 23.23.23.23:443 \n option tcplog\n" + ) } + end + # C9971 + context "when empty list of ports is provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => [], + } + end + + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n option tcplog\n" + ) } + end + # C9972 + context "when a port is provided greater than 65535" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => '80443' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /outside of range/ + end + end + # C9946 + context "when multiple ports are provided greater than 65535" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => ['80443','80444'] + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /outside of range/ + end + end + # C9973 + context "when an invalid ipv4 address is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => '2323.23.23', + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /Invalid IP address/ + end + end + # C9949 + context "when a ports parameter and a bind parameter are passed" do + let(:params) do + { + :name => 'apache', + :bind => {'192.168.0.1:80' => ['ssl']}, + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /mutually exclusive/ + end + end + context "when multiple IPs are provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => ['23.23.23.23','23.23.23.24'], + :ports => '80' + } + end + + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind 23.23.23.23:80 \n bind 23.23.23.24:80 \n option tcplog\n" + ) } + end + context "when bind options are provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '1.1.1.1', + :ports => ['80','8080'], + :bind_options => [ 'the options', 'go here' ] + } + end + + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind 1.1.1.1:80 the options go here\n bind 1.1.1.1:8080 the options go here\n option tcplog\n" ) } end context "when a comma-separated list of ports is provided" do @@ -47,7 +175,43 @@ it { should contain_concat__fragment('apache_frontend_block').with( 'order' => '15-apache-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nfrontend apache\n bind 23.23.23.23:80\n bind 23.23.23.23:443\n option tcplog\n" + 'content' => "\nfrontend apache\n bind 23.23.23.23:80 \n bind 23.23.23.23:443 \n option tcplog\n" ) } end + + context "when bind parameter is used without ipaddress parameter" do + let(:params) do + { + :name => 'apache', + :bind => {'1.1.1.1:80' => []}, + } + end + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind 1.1.1.1:80 \n option tcplog\n" + ) } + end + + context "when bind parameter is used with more complex address constructs" do + let(:params) do + { + :name => 'apache', + :bind => { + '1.1.1.1:80' => [], + ':443,:8443' => [ 'ssl', 'crt public.puppetlabs.com', 'no-sslv3' ], + '2.2.2.2:8000-8010' => [ 'ssl', 'crt public.puppetlabs.com' ], + 'fd@${FD_APP1}' => [], + '/var/run/ssl-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ] + }, + } + end + it { should contain_concat__fragment('apache_frontend_block').with( + 'order' => '15-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nfrontend apache\n bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy\n bind 1.1.1.1:80 \n bind 2.2.2.2:8000-8010 ssl crt public.puppetlabs.com\n bind :443,:8443 ssl crt public.puppetlabs.com no-sslv3\n bind fd@${FD_APP1} \n option tcplog\n" + ) } + end + + # C9950 C9951 C9952 WONTFIX end diff --git a/haproxy/spec/defines/listen_spec.rb b/haproxy/spec/defines/listen_spec.rb index ef46dcacd..c4cddc7bd 100644 --- a/haproxy/spec/defines/listen_spec.rb +++ b/haproxy/spec/defines/listen_spec.rb @@ -1,12 +1,20 @@ require 'spec_helper' describe 'haproxy::listen' do + let(:pre_condition) { 'include haproxy' } let(:title) { 'tyler' } - let(:facts) {{ :ipaddress => '1.1.1.1' }} + let(:facts) do + { + :ipaddress => '1.1.1.1', + :osfamily => 'Redhat', + :concat_basedir => '/dne', + } + end context "when only one port is provided" do let(:params) do { :name => 'croy', + :ipaddress => '1.1.1.1', :ports => '18140' } end @@ -14,9 +22,10 @@ it { should contain_concat__fragment('croy_listen_block').with( 'order' => '20-croy-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nlisten croy\n bind 1.1.1.1:18140\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + 'content' => "\nlisten croy\n bind 1.1.1.1:18140 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" ) } end + # C9940 context "when an array of ports is provided" do let(:params) do { @@ -32,9 +41,10 @@ it { should contain_concat__fragment('apache_listen_block').with( 'order' => '20-apache-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nlisten apache\n bind 23.23.23.23:80\n bind 23.23.23.23:443\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + 'content' => "\nlisten apache\n bind 23.23.23.23:80 \n bind 23.23.23.23:443 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" ) } end + # C9940 context "when a comma-separated list of ports is provided" do let(:params) do { @@ -47,7 +57,189 @@ it { should contain_concat__fragment('apache_listen_block').with( 'order' => '20-apache-00', 'target' => '/etc/haproxy/haproxy.cfg', - 'content' => "\nlisten apache\n bind 23.23.23.23:80\n bind 23.23.23.23:443\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + 'content' => "\nlisten apache\n bind 23.23.23.23:80 \n bind 23.23.23.23:443 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" ) } end + # C9962 + context "when empty list of ports is provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => [], + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + # C9963 + context "when a port is provided greater than 65535" do + let(:params) do + { + :name => 'apache', + :ipaddress => '23.23.23.23', + :ports => '80443' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /outside of range/ + end + end + # C9974 + context "when an invalid ipv4 address is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => '2323.23.23', + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /Invalid IP address/ + end + end + # C9977 + context "when a valid hostname is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => 'some-hostname', + :ports => '80' + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind some-hostname:80 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when a * is passed for ip address" do + let(:params) do + { + :name => 'apache', + :ipaddress => '*', + :ports => '80' + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind *:80 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when a bind parameter hash is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => '', + :bind => {'10.0.0.1:333' => ['ssl', 'crt', 'public.puppetlabs.com'], '192.168.122.1:8082' => []}, + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind 10.0.0.1:333 ssl crt public.puppetlabs.com\n bind 192.168.122.1:8082 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when a ports parameter and a bind parameter are passed" do + let(:params) do + { + :name => 'apache', + :bind => {'192.168.0.1:80' => ['ssl']}, + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /mutually exclusive/ + end + end + # C9977 + context "when an invalid hostname is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => '$some_hostname', + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /Invalid IP address/ + end + end + # C9974 + context "when an invalid ipv6 address is passed" do + let(:params) do + { + :name => 'apache', + :ipaddress => ':::6', + :ports => '80' + } + end + + it 'should raise error' do + expect { subject }.to raise_error Puppet::Error, /Invalid IP address/ + end + end + context "when bind options are provided" do + let(:params) do + { + :name => 'apache', + :ipaddress => '1.1.1.1', + :ports => '80', + :bind_options => [ 'the options', 'go here' ] + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind 1.1.1.1:80 the options go here\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + context "when bind parameter is used without ipaddress parameter" do + let(:params) do + { + :name => 'apache', + :bind => { '1.1.1.1:80' => [] }, + } + end + + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind 1.1.1.1:80 \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + + context "when bind parameter is used with more complex address constructs" do + let(:params) do + { + :name => 'apache', + :bind => { + '1.1.1.1:80' => [], + ':443,:8443' => [ 'ssl', 'crt public.puppetlabs.com', 'no-sslv3' ], + '2.2.2.2:8000-8010' => [ 'ssl', 'crt public.puppetlabs.com' ], + 'fd@${FD_APP1}' => [], + '/var/run/ssl-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ] + }, + } + end + it { should contain_concat__fragment('apache_listen_block').with( + 'order' => '20-apache-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nlisten apache\n bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy\n bind 1.1.1.1:80 \n bind 2.2.2.2:8000-8010 ssl crt public.puppetlabs.com\n bind :443,:8443 ssl crt public.puppetlabs.com no-sslv3\n bind fd@${FD_APP1} \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n" + ) } + end + end diff --git a/haproxy/spec/defines/peer_spec.rb b/haproxy/spec/defines/peer_spec.rb new file mode 100644 index 000000000..32ccbf82a --- /dev/null +++ b/haproxy/spec/defines/peer_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'haproxy::peer' do + let(:title) { 'dero' } + let(:facts) do + { + :ipaddress => '1.1.1.1', + :hostname => 'dero', + } + end + + context 'with a single peer' do + let(:params) do + { + :peers_name => 'tyler', + :port => 1024, + } + end + + it { should contain_concat__fragment('peers-tyler-dero').with( + 'order' => '30-peers-01-tyler-dero', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => " peer dero 1.1.1.1:1024\n" + ) } + end + + context 'remove a peer' do + let(:params) do + { + :peers_name => 'tyler', + :port => 1024, + :ensure => 'absent' + } + end + + it { should contain_concat__fragment('peers-tyler-dero').with( + 'ensure' => 'absent' + ) } + end +end diff --git a/haproxy/spec/defines/peers_spec.rb b/haproxy/spec/defines/peers_spec.rb new file mode 100644 index 000000000..d80120ce4 --- /dev/null +++ b/haproxy/spec/defines/peers_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe 'haproxy::peers' do + let(:facts) {{ :ipaddress => '1.1.1.1' }} + + context "when no options are passed" do + let(:title) { 'bar' } + + it { should contain_concat__fragment('bar_peers_block').with( + 'order' => '30-peers-00-bar', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\npeers bar\n" + ) } + end +end diff --git a/haproxy/spec/defines/userlist_spec.rb b/haproxy/spec/defines/userlist_spec.rb new file mode 100644 index 000000000..368389a9c --- /dev/null +++ b/haproxy/spec/defines/userlist_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe 'haproxy::userlist' do + let(:pre_condition) { 'include haproxy' } + let(:title) { 'admins' } + let(:facts) do + { + :ipaddress => '1.1.1.1', + :osfamily => 'Redhat', + :concat_basedir => '/dne', + } + end + + context "when users and groups are passed" do + let (:params) do + { + :name => "admins", + :users => [ + 'scott insecure-password elgato', + 'kitchen insecure-password foobar' + ], + :groups => [ + 'superadmins users kitchen scott', + 'megaadmins users kitchen' + ] + } + end + + it { should contain_concat__fragment('admins_userlist_block').with( + 'order' => '12-admins-00', + 'target' => '/etc/haproxy/haproxy.cfg', + 'content' => "\nuserlist admins\n group superadmins users kitchen scott\n group megaadmins users kitchen\n user scott insecure-password elgato\n user kitchen insecure-password foobar\n" + ) } + + end +end diff --git a/haproxy/spec/spec_helper_acceptance.rb b/haproxy/spec/spec_helper_acceptance.rb new file mode 100644 index 000000000..4639ece26 --- /dev/null +++ b/haproxy/spec/spec_helper_acceptance.rb @@ -0,0 +1,78 @@ +require 'beaker-rspec' + +UNSUPPORTED_PLATFORMS = ['Darwin', 'Suse','windows','AIX','Solaris'] + +unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no' + # This will install the latest available package on el and deb based + # systems fail on windows and osx, and install via gem on other *nixes + foss_opts = { :default_action => 'gem_install' } + + if default.is_pe?; then install_pe; else install_puppet( foss_opts ); end + + hosts.each do |host| + on host, "mkdir -p #{host['distmoduledir']}" + # Windows doesn't have a hieraconf variable + on host, "touch #{host['hieraconf']}" if fact('osfamily') != 'windows' + end +end + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Configure all nodes in nodeset + c.before :suite do + # Install module and dependencies + puppet_module_install(:source => proj_root, :module_name => 'haproxy') + hosts.each do |host| + on host, puppet('module','install','puppetlabs-stdlib'), { :acceptable_exit_codes => [0,1] } + on host, puppet('module','install','puppetlabs-concat'), { :acceptable_exit_codes => [0,1] } + if fact('osfamily') == 'RedHat' + on host, puppet('module','install','stahnma/epel'), { :acceptable_exit_codes => [0,1] } + end + if fact('operatingsystem') == 'Debian' + on host, puppet('module','install','puppetlabs-apt'), { :acceptable_exit_codes => [0,1] } + apply_manifest(%{ + include apt + include apt::backports + }) + end + if ! UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) + pp = <<-EOS + $netcat = $::osfamily ? { + 'RedHat' => $::operatingsystemmajrelease ? { + '7' => 'nmap-ncat', + default => 'nc', + }, + 'Debian' => 'netcat-openbsd', + } + package { $netcat: ensure => present, } + package { 'screen': ensure => present, } + if $::osfamily == 'RedHat' { + class { 'epel': } + service { 'iptables': ensure => stopped, } + exec { 'setenforce Permissive': + path => ['/bin','/usr/bin','/sbin','/usr/sbin'], + onlyif => 'getenforce | grep Enforcing', + } + if $::operatingsystemmajrelease == '7' { + # For `netstat` for serverspec + package { 'net-tools': ensure => present, } + } + } + EOS + apply_manifest(pp, :catch_failures => true) + + ['5556','5557'].each do |port| + shell(%{echo 'while :; do echo "HTTP/1.1 200 OK\r\n\r\nResponse on #{port}" | nc -l #{port} ; done' > /root/script-#{port}.sh}) + shell(%{/usr/bin/screen -dmS script-#{port} sh /root/script-#{port}.sh}) + sleep 1 + shell(%{netstat -tnl|grep ':#{port}'}) + end + end + end + end +end diff --git a/haproxy/spec/unit/facter/haproxy_version_spec.rb b/haproxy/spec/unit/facter/haproxy_version_spec.rb new file mode 100644 index 000000000..fbd68e6a9 --- /dev/null +++ b/haproxy/spec/unit/facter/haproxy_version_spec.rb @@ -0,0 +1,27 @@ +require "spec_helper" + +describe Facter::Util::Fact do + before { + Facter.clear + } + + context "haproxy present" do + it do + haproxy_version_output = <<-EOS + HA-Proxy version 1.5.3 2014/07/25 + Copyright 2000-2014 Willy Tarreau + EOS + Facter::Util::Resolution.expects(:which).with("haproxy").returns(true) + Facter::Util::Resolution.expects(:exec).with("haproxy -v 2>&1").returns(haproxy_version_output) + Facter.fact(:haproxy_version).value.should == "1.5.3" + end + end + + context "haproxy not present" do + it do + Facter::Util::Resolution.stubs(:exec) + Facter::Util::Resolution.expects(:which).with("haproxy").returns(false) + Facter.fact(:haproxy_version).should be_nil + end + end +end \ No newline at end of file diff --git a/haproxy/templates/fragments/_bind.erb b/haproxy/templates/fragments/_bind.erb new file mode 100644 index 000000000..e60983ad5 --- /dev/null +++ b/haproxy/templates/fragments/_bind.erb @@ -0,0 +1,23 @@ +<% require 'ipaddr' -%> +<%- if @bind -%> +<%- @bind.sort.map do |address_port, bind_params| -%> + bind <%= address_port -%> <%= Array(bind_params).join(" ") %> +<%- end -%> +<%- else -%> +<%- + Array(@ipaddress).uniq.each do |virtual_ip| (@ports.is_a?(Array) ? @ports : Array(@ports.split(","))).each do |port| + begin + IPAddr.new(virtual_ip) + valid_ip = true + rescue ArgumentError => e + valid_ip = false + end + if ! valid_ip and ! virtual_ip.match(/^[A-Za-z][A-Za-z0-9\.-]+$/) and virtual_ip != "*" + scope.function_fail(["Invalid IP address or hostname [#{virtual_ip}]"]) + end + scope.function_fail(["Port [#{port}] is outside of range 1-65535"]) if port.to_i < 1 or port.to_i > 65535 +-%> + bind <%= virtual_ip -%>:<%= port -%> <%= Array(@bind_options).join(" ") %> +<%- end -%> +<%- end -%> +<%- end -%> diff --git a/haproxy/templates/fragments/_mode.erb b/haproxy/templates/fragments/_mode.erb new file mode 100644 index 000000000..944785771 --- /dev/null +++ b/haproxy/templates/fragments/_mode.erb @@ -0,0 +1,3 @@ +<% if @mode -%> + mode <%= @mode %> +<% end -%> diff --git a/haproxy/templates/fragments/_options.erb b/haproxy/templates/fragments/_options.erb new file mode 100644 index 000000000..4a9b14919 --- /dev/null +++ b/haproxy/templates/fragments/_options.erb @@ -0,0 +1,5 @@ +<% @options.sort.each do |key, val| -%> +<% Array(val).each do |item| -%> + <%= key %> <%= item %> +<% end -%> +<% end -%> diff --git a/haproxy/templates/haproxy-base.cfg.erb b/haproxy/templates/haproxy-base.cfg.erb index f25d5c344..228d6be36 100644 --- a/haproxy/templates/haproxy-base.cfg.erb +++ b/haproxy/templates/haproxy-base.cfg.erb @@ -19,3 +19,7 @@ defaults <%= key %> <%= val %> <% end -%> <% end -%> +<% if @custom_fragment -%> + +<%= @custom_fragment %> +<% end -%> diff --git a/haproxy/templates/haproxy_backend_block.erb b/haproxy/templates/haproxy_backend_block.erb index 95114cf46..c5df88842 100644 --- a/haproxy/templates/haproxy_backend_block.erb +++ b/haproxy/templates/haproxy_backend_block.erb @@ -1,7 +1,3 @@ backend <%= @name %> -<% @options.sort.each do |key, val| -%> -<% Array(val).each do |item| -%> - <%= key %> <%= item %> -<% end -%> -<% end -%> +<%= scope.function_template(['haproxy/fragments/_options.erb']) -%> diff --git a/haproxy/templates/haproxy_balancermember.erb b/haproxy/templates/haproxy_balancermember.erb index 47c409c0b..e8aa71e8a 100644 --- a/haproxy/templates/haproxy_balancermember.erb +++ b/haproxy/templates/haproxy_balancermember.erb @@ -1,3 +1,9 @@ <% Array(@ipaddresses).zip(Array(@server_names)).each do |ipaddress,host| -%> - server <%= host %> <%= ipaddress %>:<%= Array(@ports).collect {|x|x.split(',')}.flatten.join(",#{ipaddress}:") %> <%= if @define_cookies then "cookie " + host end %> <%= Array(@options).join(" ") %> +<% if @ports -%> +<%- Array(@ports).each do |port| -%> + server <%= host %> <%= ipaddress %>:<%= port %><%= if @define_cookies then " cookie " + host end %> <%= Array(@options).sort.join(" ") %> +<%- end -%> +<% else -%> + server <%= host %> <%= ipaddress %><%= if @define_cookies then " cookie " + host end %> <%= Array(@options).sort.join(" ") %> +<%- end -%> <% end -%> diff --git a/haproxy/templates/haproxy_frontend_block.erb b/haproxy/templates/haproxy_frontend_block.erb index a1803ce4b..9e9333d0d 100644 --- a/haproxy/templates/haproxy_frontend_block.erb +++ b/haproxy/templates/haproxy_frontend_block.erb @@ -1,13 +1,5 @@ frontend <%= @name %> -<% Array(@ipaddress).uniq.each do |virtual_ip| (@ports.is_a?(Array) ? @ports : Array(@ports.split(","))).each do |port| -%> - bind <%= virtual_ip %>:<%= port %> -<% end end -%> -<% if @mode -%> - mode <%= @mode %> -<% end -%> -<% @options.sort.each do |key, val| -%> -<% Array(val).each do |item| -%> - <%= key %> <%= item %> -<% end -%> -<% end -%> +<%= scope.function_template(['haproxy/fragments/_bind.erb']) -%> +<%= scope.function_template(['haproxy/fragments/_mode.erb']) -%> +<%= scope.function_template(['haproxy/fragments/_options.erb']) -%> diff --git a/haproxy/templates/haproxy_listen_block.erb b/haproxy/templates/haproxy_listen_block.erb index 62f295469..421942cd9 100644 --- a/haproxy/templates/haproxy_listen_block.erb +++ b/haproxy/templates/haproxy_listen_block.erb @@ -1,13 +1,5 @@ listen <%= @name %> -<% Array(@ipaddress).uniq.each do |virtual_ip| (@ports.is_a?(Array) ? @ports : Array(@ports.split(","))).each do |port| -%> - bind <%= virtual_ip %>:<%= port %> -<% end end -%> -<% if @mode -%> - mode <%= @mode %> -<% end -%> -<% @options.sort.each do |key, val| -%> -<% Array(val).each do |item| -%> - <%= key %> <%= item %> -<% end -%> -<% end -%> +<%= scope.function_template(['haproxy/fragments/_bind.erb']) -%> +<%= scope.function_template(['haproxy/fragments/_mode.erb']) -%> +<%= scope.function_template(['haproxy/fragments/_options.erb']) -%> diff --git a/haproxy/templates/haproxy_peer.erb b/haproxy/templates/haproxy_peer.erb new file mode 100644 index 000000000..95aae16bf --- /dev/null +++ b/haproxy/templates/haproxy_peer.erb @@ -0,0 +1,3 @@ +<% Array(@ipaddresses).zip(Array(@server_names)).each do |ipaddress,host| -%> + peer <%= host %> <%= ipaddress %>:<%= @port %> +<% end -%> diff --git a/haproxy/templates/haproxy_peers_block.erb b/haproxy/templates/haproxy_peers_block.erb new file mode 100644 index 000000000..3cd7aaa95 --- /dev/null +++ b/haproxy/templates/haproxy_peers_block.erb @@ -0,0 +1,2 @@ + +peers <%= @name %> diff --git a/haproxy/templates/haproxy_userlist_block.erb b/haproxy/templates/haproxy_userlist_block.erb new file mode 100644 index 000000000..d6baaffd7 --- /dev/null +++ b/haproxy/templates/haproxy_userlist_block.erb @@ -0,0 +1,12 @@ + +userlist <%= @name %> +<%- Array(@groups).each do |group| -%> + <%- if group and ! group.empty? -%> + group <%= group %> + <%- end -%> +<%- end -%> +<%- Array(@users).each do |user| -%> + <%- if user and ! user.empty? -%> + user <%= user %> + <%- end -%> +<%- end -%>