From 1912a19ae2b3ae8b91ed94f99a815d5fc931b6dc Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Mon, 19 Oct 2015 15:13:54 +0200 Subject: [PATCH] Bump to latest masters Update apache to 9c1047da1d7672d5e7305844eb27282adf60bbe0 9c1047da1d7672d5e7305844eb27282adf60bbe0 Merge pull request #1226 from DavidS/MODULES-2655-fix-sslprotocol-test 72df6f3c6dbe992b60ffcb15ccb0c720ee1f7b0a (MODULES-2655) Fix acceptance testing for SSLProtocol behaviour for real 3c953ded3975b8fa1320de3095154c99649940db Merge pull request #1225 from DavidS/multiple-fixes 1d46f7b6573e6d0ebbe269fa7006575f8087bbc4 (MODULES-2655) fix acceptance tests to correctly detect SELinux 94b2f0f8dc97a66ee62184edaaf25bb5c1ba0221 (MODULES-2680) fix default nodeset to actually work a2a63959410123227745ffa46adac8cf95231616 Merge pull request #1218 from damonconway/2673 680f3a9ff04e4d7f057942d72a8834a9be205ad2 (MODULES-2673) Adding dev_packages to apache class. Allows use of httpd24u-devel from the IUS repo. 61245989cb8208286f9ba236ac2ba780dc50aa5b Merge pull request #1224 from DavidS/allow_no_docroot b63aac22781cc9cafe33aea9c300f2e36890f643 (MAINT) add a small test for no-docroot-mode 3a1a4e4b97d1f6eea785adcb751de7c483ff4302 Merge pull request #1216 from bmfurtado/MODULES-2655 bb5b27ee2757d312b60873245a0f333ff4bc8ed5 Added tests and updated docs for string and array support on ssl_protocol for apache::vhost. f57f7f75e5324f3ab857ad05c29fad4a5ea0354a (MODULES-2120) Allow empty docroot d57816b90b9639a5213794b3a408f7aa4d679ea5 Added support for both string and array on ssl_protocol for apache::vhost 8447589abcec675f3ee57e6607861e937e850877 Change SSLProtocol in apache::vhost to be space separated Update cinder to f7524dac1bab750db82a341d0fb61ba0cc7179d7 f7524dac1bab750db82a341d0fb61ba0cc7179d7 Merge "Specify a dedicated keystone user for cinderv2" 43dcec66ba41ebac2895159e7dea3cb1d4cae498 Merge "Put all the logging related parameters to the logging class" 18f2db7a1def9322a7b6b8693f5c84eafe988eff Specify a dedicated keystone user for cinderv2 d0b0f897f1ac3e1e030901ffcde2d9cf93f098d4 Merge "Remove deprecated mysql_module" 7fe7d77bf3010a1e9c6559e5435c72ed6ff4190e Put all the logging related parameters to the logging class 6e192209432e0a9a8bc2d4b9032fb5a93844bc1b Remove deprecated mysql_module Update firewall to 2d870c46e95850ff6ee8bda19f48381512be1af7 2d870c46e95850ff6ee8bda19f48381512be1af7 Merge pull request #574 from DavidS/fix-selinux 55c838db80688edf63f0e70dcf2b755885b4a3f8 (MAINT) RedHat 6 also uses unconfined_t Update glance to 3ffcc382d0ed3e3cd441830d59965dd62a2be7e0 3ffcc382d0ed3e3cd441830d59965dd62a2be7e0 Merge "Remove deprecated mysql_module" 26cbd53d991b4bbfcae1f354ab5cc16908185a3e Remove deprecated mysql_module Update haproxy to 1c218e6fca7c217a94bc6046381bd4d6449223a4 1c218e6fca7c217a94bc6046381bd4d6449223a4 Merge pull request #201 from traylenator/config_file fe6fcb1059a482587f8a8be4a010cf31ad4f92f7 (MODULES-2704) Consistent use of ::haproxy::config_file Update heat to f592e646c4b6ca1b6f06cd6e3e01ea43f692b56d f592e646c4b6ca1b6f06cd6e3e01ea43f692b56d Missing domain in keystone::domain Update ironic to 93018353468db291aa79b30656df85cfe4dee554 93018353468db291aa79b30656df85cfe4dee554 Merge "Simplify rpc_backend parameter" 8724c8f4a27e3e30fbae1e3dd1edfb573ffb652d Simplify rpc_backend parameter Update keystone to 93af53da67370bc52b4f42ac08f6c5963ce7bb4e 93af53da67370bc52b4f42ac08f6c5963ce7bb4e Merge "Federation acceptance: bump packages to latest" d2c44f731caa1ac3e57c407fc63c0c790e99e43f Replace indirection calls a88ede3fe156e8057bb237f30926a5996dce7a82 Federation acceptance: bump packages to latest Update manila to 3122525fe061364450e2e37cb293d24b2a3f2e5c 3122525fe061364450e2e37cb293d24b2a3f2e5c Merge "Put all the logging related parameters to the logging class" 0fa8d193d4b3ea8a6bf7ce379f6d703e01210960 Put all the logging related parameters to the logging class Update mysql to 87b7e4de9cdc5feae49015c1d829e2e74f6c355b 87b7e4de9cdc5feae49015c1d829e2e74f6c355b Merge pull request #766 from DavidS/modules-2683-fix-root-password-hiding 5f49c45b2eab1a655b1547397806dd024ee82b5e (MODULES-2683) fix version compare to properly suppress show_diff for root password 6527a3aa22a79eb8a7fb554c9ddee7e53f4e534f (MAINT) switch to rspec-puppet-facts Update neutron to 4b08d26f2f5a7d5f382b80a4631d7cca878f8a17 4b08d26f2f5a7d5f382b80a4631d7cca878f8a17 Merge "Delete namespaces by default" 3a1b5bec8bd4b25c0424c4bab0b0ec959d98c9b4 Merge "disable third-party software management" 4408e648f48ef8b500aa1a35018081623051c6f8 Delete namespaces by default 46a84300df5b7dda1d811a969f7660b818eeb6be Merge "dbsync should only notify services that use the db" b9a1f479cfac84c98fa96b0ffabe08a9e847c03b disable third-party software management fdf49deed8d64cea83b079b79d13d89df49926e3 dbsync should only notify services that use the db Update redis to 4a6c6a1a741354950b1ce0f31b8fdaa9254de4ed 4a6c6a1a741354950b1ce0f31b8fdaa9254de4ed Add a option to override the service provider Update stdlib to 2db7440c6798d3ea0bf2f92c66d8281b2bfcff0c 2db7440c6798d3ea0bf2f92c66d8281b2bfcff0c Merge pull request #538 from mmckinst/bool2str_enhance 6de1a6e0622f69ec22c64e72fd53ec12ae8c9111 add functionality to bool2str to return strings of your choice for a boolean 39126a7bc82797799280231fef7ef9706a113c6c Merge pull request #539 from mentat/MODULES-2696 6aa7f2db9953d81afb75a3591358ba9e0dbc6935 Add check to ensure regex does not throw for none type. 57a8485223c221aa075d09c0a7de816a26daf1b0 Merge pull request #537 from cmurphy/fix_load_module_metadata 25410c4598d3c0029fcd05adc2e305dbf5f8d902 Let load_module_metadata succeed on empty file 0f8df10084c875edac521a2307ce4caf7317b636 Rename load_module_metadata test path 5b3c623394e405ca0db5e707554a91b4252bbbad Merge pull request #536 from DavidS/improve-file_line-docs ad173f2d0552ad9ed42950aea7df8d2b22677904 (MODULES-2421) improve description of file_line Update trove to 03f5a793a63e3788d92bda067b1b342a07db3ff7 03f5a793a63e3788d92bda067b1b342a07db3ff7 Simplify rpc_backend parameter Update vcsrepo to 99e8b2e28ce9541202b8b2438a92ee8ac2b03d6a 99e8b2e28ce9541202b8b2438a92ee8ac2b03d6a Merge pull request #273 from hunner/fix_trustcert bf0f40ae4efa9095ca9a877acefdb781e1fbf1cd Fix :false to be default value Change-Id: I505e156a08c157a536ba0c922a2ef90083bbf10e --- Puppetfile | 30 +- apache/README.md | 19 +- apache/manifests/dev.pp | 2 +- apache/manifests/init.pp | 1 + apache/manifests/vhost.pp | 20 +- .../spec/acceptance/apache_parameters_spec.rb | 2 +- apache/spec/acceptance/class_spec.rb | 2 +- .../acceptance/nodesets/centos-59-x64.yml | 10 - .../acceptance/nodesets/centos-64-x64-pe.yml | 12 - .../acceptance/nodesets/centos-64-x64.yml | 11 - .../acceptance/nodesets/centos-65-x64.yml | 10 - apache/spec/acceptance/nodesets/default.yml | 5 +- apache/spec/acceptance/vhost_spec.rb | 31 +- apache/spec/defines/vhost_spec.rb | 10 + apache/templates/vhost/_docroot.erb | 2 +- apache/templates/vhost/_ssl.erb | 2 +- cinder/manifests/db/mysql.pp | 9 - cinder/manifests/init.pp | 60 +- cinder/manifests/keystone/auth.pp | 29 +- cinder/manifests/logging.pp | 70 +- .../spec/classes/cinder_keystone_auth_spec.rb | 17 + cinder/spec/classes/cinder_logging_spec.rb | 39 +- cinder/spec/classes/cinder_spec.rb | 36 +- firewall/manifests/linux/redhat.pp | 2 +- glance/manifests/api.pp | 8 - glance/manifests/db/mysql.pp | 8 - glance/manifests/registry.pp | 8 - haproxy/manifests/peer.pp | 4 +- haproxy/manifests/peers.pp | 4 +- haproxy/spec/classes/haproxy_spec.rb | 17 + haproxy/spec/defines/peer_spec.rb | 9 +- haproxy/spec/defines/peers_spec.rb | 9 +- heat/manifests/keystone/domain.pp | 2 +- .../spec/classes/heat_keystone_domain_spec.rb | 2 +- ironic/manifests/init.pp | 8 +- keystone/lib/puppet/provider/keystone.rb | 36 + .../provider/keystone_tenant/openstack.rb | 32 +- .../provider/keystone_user/openstack.rb | 54 +- .../provider/keystone_user_role/openstack.rb | 34 +- .../spec/acceptance/basic_keystone_spec.rb | 17 +- ...stone_federation_identity_provider_spec.rb | 43 +- .../acceptance/keystone_wsgi_apache_spec.rb | 17 +- keystone/spec/unit/provider/keystone_spec.rb | 135 +++- .../keystone_tenant/openstack_spec.rb | 23 +- .../provider/keystone_user/openstack_spec.rb | 646 ++++++++---------- .../keystone_user_role/openstack_spec.rb | 300 +++----- manila/manifests/init.pp | 39 +- manila/manifests/logging.pp | 257 +++++++ manila/spec/classes/manila_logging_spec.rb | 143 ++++ manila/spec/classes/manila_spec.rb | 37 +- mysql/Gemfile | 2 +- mysql/manifests/server/root_password.pp | 2 +- mysql/spec/acceptance/mysql_server_spec.rb | 18 +- mysql/spec/classes/graceful_failures_spec.rb | 20 +- mysql/spec/classes/mycnf_template_spec.rb | 116 ++-- mysql/spec/classes/mysql_bindings_spec.rb | 46 +- mysql/spec/classes/mysql_client_spec.rb | 48 +- .../mysql_server_account_security_spec.rb | 34 +- .../spec/classes/mysql_server_backup_spec.rb | 600 ++++++++-------- .../spec/classes/mysql_server_monitor_spec.rb | 55 +- .../classes/mysql_server_mysqltuner_spec.rb | 66 +- mysql/spec/classes/mysql_server_spec.rb | 340 ++++----- mysql/spec/defines/mysql_db_spec.rb | 112 +-- mysql/spec/spec_helper.rb | 4 +- neutron/manifests/agents/dhcp.pp | 4 +- neutron/manifests/agents/l3.pp | 4 +- neutron/manifests/agents/n1kv_vem.pp | 3 + neutron/manifests/db/sync.pp | 2 +- neutron/manifests/plugins/ml2/bigswitch.pp | 1 + neutron/manifests/plugins/ml2/cisco.pp | 1 + neutron/manifests/plugins/plumgrid.pp | 1 + neutron/manifests/server.pp | 2 +- .../spec/classes/neutron_agents_dhcp_spec.rb | 2 +- .../spec/classes/neutron_agents_l3_spec.rb | 2 +- neutron/spec/classes/neutron_server_spec.rb | 2 +- redis/manifests/init.pp | 6 + redis/manifests/params.pp | 1 + redis/manifests/service.pp | 1 + stdlib/README.markdown | 91 ++- stdlib/lib/facter/pe_version.rb | 9 +- .../lib/puppet/parser/functions/bool2str.rb | 26 +- .../parser/functions/load_module_metadata.rb | 16 +- stdlib/lib/puppet/type/file_line.rb | 11 +- stdlib/spec/functions/bool2str_spec.rb | 6 + stdlib/spec/functions/load_module_metadata.rb | 16 - .../functions/load_module_metadata_spec.rb | 29 + stdlib/spec/unit/facter/pe_version_spec.rb | 12 + trove/manifests/api.pp | 4 +- trove/manifests/conductor.pp | 4 +- trove/manifests/guestagent.pp | 4 +- trove/manifests/init.pp | 8 +- trove/manifests/taskmanager.pp | 4 +- trove/spec/classes/trove_api_spec.rb | 8 +- trove/spec/classes/trove_conductor_spec.rb | 8 +- trove/spec/classes/trove_guestagent_spec.rb | 8 +- trove/spec/classes/trove_taskmanager_spec.rb | 8 +- vcsrepo/Gemfile | 1 + vcsrepo/lib/puppet/provider/vcsrepo/svn.rb | 2 +- vcsrepo/lib/puppet/type/vcsrepo.rb | 2 +- .../unit/puppet/provider/vcsrepo/svn_spec.rb | 10 +- 100 files changed, 2335 insertions(+), 1770 deletions(-) delete mode 100644 apache/spec/acceptance/nodesets/centos-59-x64.yml delete mode 100644 apache/spec/acceptance/nodesets/centos-64-x64-pe.yml delete mode 100644 apache/spec/acceptance/nodesets/centos-64-x64.yml delete mode 100644 apache/spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 manila/manifests/logging.pp create mode 100644 manila/spec/classes/manila_logging_spec.rb delete mode 100755 stdlib/spec/functions/load_module_metadata.rb create mode 100755 stdlib/spec/functions/load_module_metadata_spec.rb diff --git a/Puppetfile b/Puppetfile index a88f61ee9..d03bda76e 100644 --- a/Puppetfile +++ b/Puppetfile @@ -1,5 +1,5 @@ mod 'apache', - :commit => '22ed02711ea7afee8a17c6b0ab7eb24d772d2b6e', + :commit => '9c1047da1d7672d5e7305844eb27282adf60bbe0', :git => 'https://github.com/puppetlabs/puppetlabs-apache.git' mod 'aviator', @@ -19,7 +19,7 @@ mod 'certmonger', :git => 'https://github.com/rcritten/puppet-certmonger.git' mod 'cinder', - :commit => '17026a35ecc28e28075bc13580b9740d641094ac', + :commit => 'f7524dac1bab750db82a341d0fb61ba0cc7179d7', :git => 'https://github.com/openstack/puppet-cinder.git' mod 'common', @@ -35,7 +35,7 @@ mod 'corosync', :git => 'https://github.com/puppetlabs/puppetlabs-corosync.git' mod 'firewall', - :commit => '6755b959004f176844cb143690cc83ba621c40de', + :commit => '2d870c46e95850ff6ee8bda19f48381512be1af7', :git => 'https://github.com/puppetlabs/puppetlabs-firewall.git' mod 'galera', @@ -43,7 +43,7 @@ mod 'galera', :git => 'https://github.com/redhat-openstack/puppet-galera.git' mod 'glance', - :commit => 'd6ad1f504eda3f1f0e0613ece9392dd8f78bf7b5', + :commit => '3ffcc382d0ed3e3cd441830d59965dd62a2be7e0', :git => 'https://github.com/openstack/puppet-glance.git' mod 'gluster', @@ -55,11 +55,11 @@ mod 'gnocchi', :git => 'https://github.com/openstack/puppet-gnocchi.git' mod 'haproxy', - :commit => 'cdcbc19ac3389aadc5d7ec1e9d0631de28e06bf7', + :commit => '1c218e6fca7c217a94bc6046381bd4d6449223a4', :git => 'https://github.com/puppetlabs/puppetlabs-haproxy.git' mod 'heat', - :commit => '06953c3d4493e405343704b1beeb1e610cfa75e6', + :commit => 'f592e646c4b6ca1b6f06cd6e3e01ea43f692b56d', :git => 'https://github.com/openstack/puppet-heat.git' mod 'horizon', @@ -75,7 +75,7 @@ mod 'ipa', :git => 'https://github.com/xbezdick/puppet-ipa-1.git' mod 'ironic', - :commit => '50ec0e11608930f5286ee0913d1cd6fde8bf8a55', + :commit => '93018353468db291aa79b30656df85cfe4dee554', :git => 'https://github.com/openstack/puppet-ironic.git' mod 'keepalived', @@ -83,11 +83,11 @@ mod 'keepalived', :git => 'https://github.com/Unyonsys/puppet-module-keepalived.git' mod 'keystone', - :commit => 'cc2f08164aea815c8e6f1a849edfee6aa75f7dcc', + :commit => '93af53da67370bc52b4f42ac08f6c5963ce7bb4e', :git => 'https://github.com/openstack/puppet-keystone.git' mod 'manila', - :commit => 'd8fee807df66314ee3e5c68ee669e8826e327eef', + :commit => '3122525fe061364450e2e37cb293d24b2a3f2e5c', :git => 'https://github.com/openstack/puppet-manila.git' mod 'memcached', @@ -107,7 +107,7 @@ mod 'mongodb', :git => 'https://github.com/puppetlabs/puppetlabs-mongodb.git' mod 'mysql', - :commit => '5e6db0bb0fd8b28bb9c7d8f23e67e6ddb8abf616', + :commit => '87b7e4de9cdc5feae49015c1d829e2e74f6c355b', :git => 'https://github.com/puppetlabs/puppetlabs-mysql.git' mod 'n1k_vsm', @@ -119,7 +119,7 @@ mod 'nagios', :git => 'https://github.com/gildub/puppet-nagios-openstack.git' mod 'neutron', - :commit => 'ee10d14987a96fb82cc0905827f7891e8e6ecbb8', + :commit => '4b08d26f2f5a7d5f382b80a4631d7cca878f8a17', :git => 'https://github.com/openstack/puppet-neutron.git' mod 'nova', @@ -159,7 +159,7 @@ mod 'rabbitmq', :git => 'https://github.com/puppetlabs/puppetlabs-rabbitmq.git' mod 'redis', - :commit => 'df4e2077220b13751c6f4fa89e714c0be72a65a7', + :commit => '4a6c6a1a741354950b1ce0f31b8fdaa9254de4ed', :git => 'https://github.com/arioch/puppet-redis.git' mod 'remote', @@ -187,7 +187,7 @@ mod 'staging', :git => 'https://github.com/nanliu/puppet-staging.git' mod 'stdlib', - :commit => '4e62223801d118bb427a230b4571a911399ea859', + :commit => '2db7440c6798d3ea0bf2f92c66d8281b2bfcff0c', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib.git' mod 'swift', @@ -211,7 +211,7 @@ mod 'tripleo', :git => 'https://github.com/openstack/puppet-tripleo.git' mod 'trove', - :commit => '045d929556389a631a34a68b011dc87b960fb9a6', + :commit => '03f5a793a63e3788d92bda067b1b342a07db3ff7', :git => 'https://github.com/openstack/puppet-trove' mod 'tuskar', @@ -219,7 +219,7 @@ mod 'tuskar', :git => 'https://github.com/openstack/puppet-tuskar.git' mod 'vcsrepo', - :commit => '279be07607dd132f9446291cf1afa5ef2320632a', + :commit => '99e8b2e28ce9541202b8b2438a92ee8ac2b03d6a', :git => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git' mod 'vlan', diff --git a/apache/README.md b/apache/README.md index 5066caac9..51d2f5dad 100644 --- a/apache/README.md +++ b/apache/README.md @@ -133,6 +133,7 @@ [`logroot`]: #logroot [Log security]: http://httpd.apache.org/docs/current/logs.html#security +[`manage_docroot`]: #manage_docroot [`manage_user`]: #manage_user [`manage_group`]: #manage_group [`MaxConnectionsPerChild`]: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxconnectionsperchild @@ -888,6 +889,20 @@ Configures a default virtual host when the class is declared. Valid options: Boo To configure [customized virtual hosts][Configuring virtual hosts], set this parameter's value to 'false'. +##### `dev_packages` + +Configures a specific dev package to use. Valid options: String. Default: 'OS default httpd dev package'. + +Example for using httpd 2.4 from the IUS yum repo: + +~~~ puppet +include ::apache::dev +class { 'apache': + apache_name => 'httpd24u', + dev_packages => 'httpd24u-devel', +} +~~~ + ##### `docroot` Sets the default [`DocumentRoot`][] location. Default: Determined by your operating system. @@ -1886,6 +1901,8 @@ Sets the list of resources to look for when a client requests an index of the di **Required**. Sets the [`DocumentRoot`][] location, from which Apache serves files. +If `docroot` and [`manage_docroot`][] are both set to `false`, no [`DocumentRoot`][] will be set and the accompanying `` block will not be created. + ##### `docroot_group` Sets group access to the [`docroot`][] directory. Defaults to 'root'. @@ -3046,7 +3063,7 @@ Specifies the SSL certification. Defaults are based on your OS: '/etc/pki/tls/ce ##### `ssl_protocol` -Specifies [SSLProtocol](http://httpd.apache.org/docs/current/mod/mod_ssl.html#sslprotocol). Expects an array of accepted protocols. Defaults to 'all', '-SSLv2', '-SSLv3'. +Specifies [SSLProtocol](http://httpd.apache.org/docs/current/mod/mod_ssl.html#sslprotocol). Expects an array or space separated string of accepted protocols. Defaults to 'all', '-SSLv2', '-SSLv3'. ##### `ssl_cipher` diff --git a/apache/manifests/dev.pp b/apache/manifests/dev.pp index b1947e934..fdebf59f5 100644 --- a/apache/manifests/dev.pp +++ b/apache/manifests/dev.pp @@ -1,6 +1,6 @@ class apache::dev { include ::apache::params - $packages = $::apache::params::dev_packages + $packages = $::apache::dev_packages if $packages { # FreeBSD doesn't have dev packages to install package { $packages: ensure => present, diff --git a/apache/manifests/init.pp b/apache/manifests/init.pp index 7baa65713..5db9e90c7 100644 --- a/apache/manifests/init.pp +++ b/apache/manifests/init.pp @@ -28,6 +28,7 @@ $default_ssl_crl = undef, $default_ssl_crl_check = undef, $default_type = 'none', + $dev_packages = $::apache::params::dev_packages, $ip = undef, $service_enable = true, $service_manage = true, diff --git a/apache/manifests/vhost.pp b/apache/manifests/vhost.pp index 25530bccb..36d425ef1 100644 --- a/apache/manifests/vhost.pp +++ b/apache/manifests/vhost.pp @@ -227,6 +227,12 @@ if $limit_request_field_size { validate_integer($limit_request_field_size) } + + # Validate the docroot as a string if: + # - $manage_docroot is true + if $manage_docroot { + validate_string($docroot) + } # Input validation ends if $ssl and $ensure == 'present' { @@ -271,7 +277,7 @@ # This ensures that the docroot exists # But enables it to be specified across multiple vhost resources - if ! defined(File[$docroot]) and $manage_docroot { + if $manage_docroot and $docroot and ! defined(File[$docroot]) { file { $docroot: ensure => directory, owner => $docroot_owner, @@ -443,7 +449,7 @@ fail("Apache::Vhost[${name}]: 'directories' must be either a Hash or an Array of Hashes") } $_directories = $directories - } else { + } elsif $docroot { $_directory = { provider => 'directory', path => $docroot, @@ -518,10 +524,12 @@ # Template uses: # - $virtual_docroot # - $docroot - concat::fragment { "${name}-docroot": - target => "${priority_real}${filename}.conf", - order => 10, - content => template('apache/vhost/_docroot.erb'), + if $docroot { + concat::fragment { "${name}-docroot": + target => "${priority_real}${filename}.conf", + order => 10, + content => template('apache/vhost/_docroot.erb'), + } } # Template uses: diff --git a/apache/spec/acceptance/apache_parameters_spec.rb b/apache/spec/acceptance/apache_parameters_spec.rb index 4c6fa7f56..c46a22043 100644 --- a/apache/spec/acceptance/apache_parameters_spec.rb +++ b/apache/spec/acceptance/apache_parameters_spec.rb @@ -358,7 +358,7 @@ class { 'apache': describe 'setup' do it 'applies cleanly' do pp = <<-EOS - if $::osfamily == 'RedHat' and $::selinux { + if $::osfamily == 'RedHat' and "$::selinux" == "true" { $semanage_package = $::operatingsystemmajrelease ? { '5' => 'policycoreutils', default => 'policycoreutils-python', diff --git a/apache/spec/acceptance/class_spec.rb b/apache/spec/acceptance/class_spec.rb index 0a7d67bbb..0cf1c36f9 100644 --- a/apache/spec/acceptance/class_spec.rb +++ b/apache/spec/acceptance/class_spec.rb @@ -45,7 +45,7 @@ class { 'apache': } # Using puppet_apply as a helper it 'should work with no errors' do pp = <<-EOS - if $::osfamily == 'RedHat' and $::selinux { + if $::osfamily == 'RedHat' and "$::selinux" == "true" { $semanage_package = $::operatingsystemmajrelease ? { '5' => 'policycoreutils', default => 'policycoreutils-python', diff --git a/apache/spec/acceptance/nodesets/centos-59-x64.yml b/apache/spec/acceptance/nodesets/centos-59-x64.yml deleted file mode 100644 index 2ad90b86a..000000000 --- a/apache/spec/acceptance/nodesets/centos-59-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-59-x64: - roles: - - master - platform: el-5-x86_64 - box : centos-59-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: git diff --git a/apache/spec/acceptance/nodesets/centos-64-x64-pe.yml b/apache/spec/acceptance/nodesets/centos-64-x64-pe.yml deleted file mode 100644 index 7d9242f1b..000000000 --- a/apache/spec/acceptance/nodesets/centos-64-x64-pe.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - - database - - dashboard - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: pe diff --git a/apache/spec/acceptance/nodesets/centos-64-x64.yml b/apache/spec/acceptance/nodesets/centos-64-x64.yml deleted file mode 100644 index ce47212a8..000000000 --- a/apache/spec/acceptance/nodesets/centos-64-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - log_level: debug - type: git diff --git a/apache/spec/acceptance/nodesets/centos-65-x64.yml b/apache/spec/acceptance/nodesets/centos-65-x64.yml deleted file mode 100644 index 4e2cb809e..000000000 --- a/apache/spec/acceptance/nodesets/centos-65-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-65-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/apache/spec/acceptance/nodesets/default.yml b/apache/spec/acceptance/nodesets/default.yml index ce47212a8..00e141d09 100644 --- a/apache/spec/acceptance/nodesets/default.yml +++ b/apache/spec/acceptance/nodesets/default.yml @@ -1,10 +1,9 @@ HOSTS: - centos-64-x64: + centos-66-x64: roles: - master platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box + box : puppetlabs/centos-6.6-64-nocm hypervisor : vagrant CONFIG: log_level: debug diff --git a/apache/spec/acceptance/vhost_spec.rb b/apache/spec/acceptance/vhost_spec.rb index b5d51e91f..e903b38d8 100644 --- a/apache/spec/acceptance/vhost_spec.rb +++ b/apache/spec/acceptance/vhost_spec.rb @@ -1287,7 +1287,7 @@ class { 'apache::mod::fastcgi': } describe 'additional_includes' do it 'applies cleanly' do pp = <<-EOS - if $::osfamily == 'RedHat' and $::selinux { + if $::osfamily == 'RedHat' and "$::selinux" == "true" { $semanage_package = $::operatingsystemmajrelease ? { '5' => 'policycoreutils', default => 'policycoreutils-python', @@ -1339,4 +1339,33 @@ class { 'apache': } it { is_expected.to be_file } end end + + describe 'SSLProtocol directive' do + it 'applies cleanly' do + pp = <<-EOS + class { 'apache': } + apache::vhost { 'test.server': + docroot => '/tmp', + ssl => true, + ssl_protocol => ['All', '-SSLv2'], + } + apache::vhost { 'test2.server': + docroot => '/tmp', + ssl => true, + ssl_protocol => 'All -SSLv2', + } + EOS + apply_manifest(pp, :catch_failures => true) + end + + describe file("#{$vhost_dir}/25-test.server.conf") do + it { is_expected.to be_file } + it { is_expected.to contain 'SSLProtocol *All -SSLv2' } + end + + describe file("#{$vhost_dir}/25-test2.server.conf") do + it { is_expected.to be_file } + it { is_expected.to contain 'SSLProtocol *All -SSLv2' } + end + end end diff --git a/apache/spec/defines/vhost_spec.rb b/apache/spec/defines/vhost_spec.rb index 6fd59f915..2964e9b28 100644 --- a/apache/spec/defines/vhost_spec.rb +++ b/apache/spec/defines/vhost_spec.rb @@ -612,6 +612,16 @@ it { is_expected.to_not contain_concat__fragment('rspec.example.com-limits') } it { is_expected.to contain_concat__fragment('rspec.example.com-file_footer') } end + context 'when not setting nor managing the docroot' do + let :params do + { + 'docroot' => false, + 'manage_docroot' => false, + } + end + it { is_expected.to compile } + it { is_expected.not_to contain_concat__fragment('rspec.example.com-docroot') } + end end describe 'access logs' do let :facts do diff --git a/apache/templates/vhost/_docroot.erb b/apache/templates/vhost/_docroot.erb index 6039fa63c..b67998b4b 100644 --- a/apache/templates/vhost/_docroot.erb +++ b/apache/templates/vhost/_docroot.erb @@ -2,6 +2,6 @@ ## Vhost docroot <% if @virtual_docroot -%> VirtualDocumentRoot "<%= @virtual_docroot %>" -<% else -%> +<% elsif @docroot -%> DocumentRoot "<%= @docroot %>" <% end -%> diff --git a/apache/templates/vhost/_ssl.erb b/apache/templates/vhost/_ssl.erb index e99b739a6..a3d76fb13 100644 --- a/apache/templates/vhost/_ssl.erb +++ b/apache/templates/vhost/_ssl.erb @@ -26,7 +26,7 @@ SSLProxyEngine On <%- end -%> <%- if @ssl_protocol -%> - SSLProtocol <%= @ssl_protocol %> + SSLProtocol <%= [@ssl_protocol].flatten.compact.join(' ') %> <%- end -%> <%- if @ssl_cipher -%> SSLCipherSuite <%= @ssl_cipher %> diff --git a/cinder/manifests/db/mysql.pp b/cinder/manifests/db/mysql.pp index 8fd06be8e..aac2c658a 100644 --- a/cinder/manifests/db/mysql.pp +++ b/cinder/manifests/db/mysql.pp @@ -34,9 +34,6 @@ # # === Deprecated Parameters # -# [*mysql_module*] -# (Deprecated) Deprecated. Does nothing. -# class cinder::db::mysql ( $password, $dbname = 'cinder', @@ -46,14 +43,8 @@ $charset = 'utf8', $collate = 'utf8_general_ci', $cluster_id = 'localzone', - # DEPRECATED - $mysql_module = undef, ) { - if $mysql_module { - warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') - } - validate_string($password) ::openstacklib::db::mysql { 'cinder': diff --git a/cinder/manifests/init.pp b/cinder/manifests/init.pp index 18102b1b4..a2391bf58 100644 --- a/cinder/manifests/init.pp +++ b/cinder/manifests/init.pp @@ -10,15 +10,11 @@ # # [*verbose*] # (Optional) Should the daemons log verbose messages -# Defaults to 'false' +# Defaults to undef. # # [*debug*] # (Optional) Should the daemons log debug messages -# Defaults to 'false' -# -# [*use_syslog*] -# (Optional) Use syslog for logging. -# Defaults to false. +# Defaults to undef. # # [*rpc_backend*] # (Optional) Use these options to configure the RabbitMQ message system. @@ -139,9 +135,9 @@ # # [*qpid_reconnect_interval_max*] # -# [*use_syslog] -# Use syslog for logging. -# (Optional) Defaults to false. +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to undef. # # [*database_connection*] # Url used to connect to database. @@ -174,16 +170,16 @@ # # [*use_stderr*] # (optional) Use stderr for logging -# Defaults to true +# Defaults to undef. # # [*log_facility*] -# Syslog facility to receive log lines. -# (Optional) Defaults to LOG_USER. +# (Optional) Syslog facility to receive log lines. +# Defaults to undef. # # [*log_dir*] # (optional) Directory where logs should be stored. # If set to boolean false, it will not log to any directory. -# Defaults to $::os_service_default +# Defaults to undef. # # [*use_ssl*] # (optional) Enable SSL on the API server @@ -230,10 +226,6 @@ # Defaults to: $::cinder::params::lock_path # # === Deprecated Parameters -# -# [*mysql_module*] -# DEPRECATED. Does nothing. -# class cinder ( $database_connection = undef, $database_idle_timeout = undef, @@ -278,28 +270,23 @@ $cert_file = false, $key_file = false, $api_paste_config = '/etc/cinder/api-paste.ini', - $use_syslog = false, - $use_stderr = true, - $log_facility = 'LOG_USER', - $log_dir = $::os_service_default, - $verbose = false, - $debug = false, + $use_syslog = undef, + $use_stderr = undef, + $log_facility = undef, + $log_dir = undef, + $verbose = undef, + $debug = undef, $storage_availability_zone = 'nova', $default_availability_zone = false, $enable_v1_api = true, $enable_v2_api = true, $lock_path = $::cinder::params::lock_path, - # DEPRECATED PARAMETERS - $mysql_module = undef, ) { include ::cinder::db + include ::cinder::logging include ::cinder::params - if $mysql_module { - warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') - } - if $use_ssl { if !$cert_file { fail('The cert_file parameter is required when use_ssl is set to true') @@ -400,10 +387,6 @@ } cinder_config { - 'DEFAULT/log_dir': value => $log_dir; - 'DEFAULT/verbose': value => $verbose; - 'DEFAULT/debug': value => $debug; - 'DEFAULT/use_stderr': value => $use_stderr; 'DEFAULT/api_paste_config': value => $api_paste_config; 'DEFAULT/rpc_backend': value => $rpc_backend; 'DEFAULT/storage_availability_zone': value => $storage_availability_zone; @@ -425,17 +408,6 @@ } } - if $use_syslog { - cinder_config { - 'DEFAULT/use_syslog': value => true; - 'DEFAULT/syslog_log_facility': value => $log_facility; - } - } else { - cinder_config { - 'DEFAULT/use_syslog': value => false; - } - } - # V1/V2 APIs cinder_config { 'DEFAULT/enable_v1_api': value => $enable_v1_api; diff --git a/cinder/manifests/keystone/auth.pp b/cinder/manifests/keystone/auth.pp index 5890a768d..df62f7fd0 100644 --- a/cinder/manifests/keystone/auth.pp +++ b/cinder/manifests/keystone/auth.pp @@ -10,6 +10,12 @@ # [*email*] # Email for Cinder user. Optional. Defaults to 'cinder@localhost'. # +# [*password_user_v2*] +# Password for Cinder v2 user. Optional. Defaults to undef. +# +# [*email_user_v2*] +# Email for Cinder v2 user. Optional. Defaults to 'cinderv2@localhost'. +# # [*auth_name*] # Username for Cinder service. Optional. Defaults to 'cinder'. # @@ -26,10 +32,17 @@ # [*configure_user*] # Should the service user be configured? Optional. Defaults to 'true'. # +# [*configure_user_v2*] +# Should the service user be configured for cinder v2? Optional. Defaults to 'false'. +# # [*configure_user_role*] # Should the admin role be configured for the service user? # Optional. Defaults to 'true'. # +# [*configure_user_role_v2*] +# Should the admin role be configured for the service user for cinder v2? +# Optional. Defaults to 'false'. +# # [*service_name*] # (optional) Name of the service. # Defaults to the value of auth_name, but must differ from the value @@ -72,6 +85,9 @@ # [*tenant*] # Tenant for Cinder user. Optional. Defaults to 'services'. # +# [*tenant_user_v2*] +# Tenant for Cinder v2 user. Optional. Defaults to 'services'. +# # [*public_url*] # (optional) The endpoint's public url. (Defaults to 'http://127.0.0.1:8776/v1/%(tenant_id)s') # This url should *not* contain any trailing '/'. @@ -151,10 +167,13 @@ # class cinder::keystone::auth ( $password, + $password_user_v2 = undef, $auth_name = 'cinder', $auth_name_v2 = 'cinderv2', $tenant = 'services', + $tenant_user_v2 = 'services', $email = 'cinder@localhost', + $email_user_v2 = 'cinderv2@localhost', $public_url = 'http://127.0.0.1:8776/v1/%(tenant_id)s', $internal_url = 'http://127.0.0.1:8776/v1/%(tenant_id)s', $admin_url = 'http://127.0.0.1:8776/v1/%(tenant_id)s', @@ -164,7 +183,9 @@ $configure_endpoint = true, $configure_endpoint_v2 = true, $configure_user = true, + $configure_user_v2 = false, $configure_user_role = true, + $configure_user_role_v2 = false, $service_name = undef, $service_name_v2 = undef, $service_type = 'volume', @@ -297,13 +318,17 @@ } keystone::resource::service_identity { 'cinderv2': - configure_user => false, - configure_user_role => false, + configure_user => $configure_user_v2, + configure_user_role => $configure_user_role_v2, configure_endpoint => $configure_endpoint_v2, service_type => $service_type_v2, service_description => $service_description_v2, service_name => $real_service_name_v2, region => $region, + auth_name => $auth_name_v2, + password => $password_user_v2, + email => $email_user_v2, + tenant => $tenant_user_v2, public_url => $public_url_v2_real, admin_url => $admin_url_v2_real, internal_url => $internal_url_v2_real, diff --git a/cinder/manifests/logging.pp b/cinder/manifests/logging.pp index 2e8cbad29..ec75a9744 100644 --- a/cinder/manifests/logging.pp +++ b/cinder/manifests/logging.pp @@ -1,9 +1,34 @@ # == Class: cinder::logging # -# Cinder extended logging configuration +# Cinder logging configuration # # === Parameters # +# [*verbose*] +# (Optional) Should the daemons log verbose messages +# Defaults to $::os_service_default +# +# [*debug*] +# (Optional) Should the daemons log debug messages +# Defaults to $::os_service_default +# +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to $::os_service_default +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to $::os_service_default +# +# [*log_facility*] +# (Optional) Syslog facility to receive log lines. +# Defaults to $::os_service_default +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false, it will not log to any directory. +# Defaults to $::os_service_default +# # [*logging_context_format_string*] # (Optional) Format string to use for log messages with context. # Defaults to $::os_service_default @@ -33,7 +58,7 @@ # # [*default_log_levels*] # (optional) Hash of logger (keys) and level (values) pairs. -# Defaults to undef. +# Defaults to $::os_service_default. # Example: # { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', # 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', @@ -66,12 +91,18 @@ # Example: 'Y-%m-%d %H:%M:%S' # class cinder::logging( + $use_syslog = $::os_service_default, + $use_stderr = $::os_service_default, + $log_facility = $::os_service_default, + $log_dir = $::os_service_default, + $verbose = $::os_service_default, + $debug = $::os_service_default, $logging_context_format_string = $::os_service_default, $logging_default_format_string = $::os_service_default, $logging_debug_format_suffix = $::os_service_default, $logging_exception_prefix = $::os_service_default, $log_config_append = $::os_service_default, - $default_log_levels = undef, + $default_log_levels = $::os_service_default, $publish_errors = $::os_service_default, $fatal_deprecations = $::os_service_default, $instance_format = $::os_service_default, @@ -79,7 +110,29 @@ $log_date_format = $::os_service_default, ) { + # NOTE(spredzy): In order to keep backward compatibility we rely on the pick function + # to use cinder:: if cinder::logging:: isn't specified. + $use_syslog_real = pick($::cinder::use_syslog,$use_syslog) + $use_stderr_real = pick($::cinder::use_stderr,$use_stderr) + $log_facility_real = pick($::cinder::log_facility,$log_facility) + $log_dir_real = pick($::cinder::log_dir,$log_dir) + $verbose_real = pick($::cinder::verbose,$verbose) + $debug_real = pick($::cinder::debug,$debug) + + if is_service_default($default_log_levels) { + $default_log_levels_real = $default_log_levels + } else { + $default_log_levels_real = join(sort(join_keys_to_values($default_log_levels, '=')), ',') + } + cinder_config { + 'DEFAULT/use_syslog' : value => $use_syslog_real; + 'DEFAULT/use_stderr' : value => $use_stderr_real; + 'DEFAULT/syslog_log_facility' : value => $log_facility_real; + 'DEFAULT/log_dir' : value => $log_dir_real; + 'DEFAULT/verbose' : value => $verbose_real; + 'DEFAULT/debug' : value => $debug_real; + 'DEFAULT/default_log_levels' : value => $default_log_levels_real; 'DEFAULT/logging_context_format_string' : value => $logging_context_format_string; 'DEFAULT/logging_default_format_string' : value => $logging_default_format_string; 'DEFAULT/logging_debug_format_suffix' : value => $logging_debug_format_suffix; @@ -92,15 +145,4 @@ 'DEFAULT/log_date_format' : value => $log_date_format; } - if $default_log_levels { - cinder_config { - 'DEFAULT/default_log_levels' : - value => join(sort(join_keys_to_values($default_log_levels, '=')), ','); - } - } else { - cinder_config { - 'DEFAULT/default_log_levels' : ensure => absent; - } - } - } diff --git a/cinder/spec/classes/cinder_keystone_auth_spec.rb b/cinder/spec/classes/cinder_keystone_auth_spec.rb index f129eeb98..40227d8de 100644 --- a/cinder/spec/classes/cinder_keystone_auth_spec.rb +++ b/cinder/spec/classes/cinder_keystone_auth_spec.rb @@ -159,6 +159,23 @@ end + describe 'when user and user role for v2 is_expected.to be configured' do + before do + params.merge!( + :configure_user_v2 => true, + :configure_user_role_v2 => true, + ) + end + + it { is_expected.to contain_keystone__resource__service_identity('cinderv2').with( + :configure_user => true, + :configure_user_role => true, + :email => 'cinderv2@localhost', + :tenant => 'services' + ) } + + end + describe 'when overriding service names' do before do diff --git a/cinder/spec/classes/cinder_logging_spec.rb b/cinder/spec/classes/cinder_logging_spec.rb index 0bc39b2b6..a0e2958c3 100644 --- a/cinder/spec/classes/cinder_logging_spec.rb +++ b/cinder/spec/classes/cinder_logging_spec.rb @@ -15,7 +15,7 @@ :logging_exception_prefix => '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s', :log_config_append => '/etc/cinder/logging.conf', :publish_errors => true, - :default_log_levels => { + :default_log_levels => { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', 'iso8601' => 'WARN', @@ -24,11 +24,26 @@ :instance_format => '[instance: %(uuid)s] ', :instance_uuid_format => '[instance: %(uuid)s] ', :log_date_format => '%Y-%m-%d %H:%M:%S', + :use_syslog => false, + :use_stderr => false, + :log_facility => 'LOG_USER', + :log_dir => '/var/log', + :verbose => true, + :debug => true, } end shared_examples_for 'cinder-logging' do + context 'with basic logging options and default settings' do + it_configures 'basic default logging settings' + end + + context 'with basic logging options and non-default settings' do + before { params.merge!( log_params ) } + it_configures 'basic non-default logging settings' + end + context 'with extended logging options' do before { params.merge!( log_params ) } it_configures 'logging params set' @@ -36,6 +51,28 @@ end + shared_examples 'basic default logging settings' do + it 'configures cinder logging settins with default values' do + is_expected.to contain_cinder_config('DEFAULT/use_syslog').with(:value => '') + is_expected.to contain_cinder_config('DEFAULT/use_stderr').with(:value => '') + is_expected.to contain_cinder_config('DEFAULT/syslog_log_facility').with(:value => '') + is_expected.to contain_cinder_config('DEFAULT/log_dir').with(:value => '') + is_expected.to contain_cinder_config('DEFAULT/verbose').with(:value => '') + is_expected.to contain_cinder_config('DEFAULT/debug').with(:value => '') + end + end + + shared_examples 'basic non-default logging settings' do + it 'configures cinder logging settins with non-default values' do + is_expected.to contain_cinder_config('DEFAULT/use_syslog').with(:value => 'false') + is_expected.to contain_cinder_config('DEFAULT/use_stderr').with(:value => 'false') + is_expected.to contain_cinder_config('DEFAULT/syslog_log_facility').with(:value => 'LOG_USER') + is_expected.to contain_cinder_config('DEFAULT/log_dir').with(:value => '/var/log') + is_expected.to contain_cinder_config('DEFAULT/verbose').with(:value => 'true') + is_expected.to contain_cinder_config('DEFAULT/debug').with(:value => 'true') + end + end + shared_examples_for 'logging params set' do it 'enables logging params' do is_expected.to contain_cinder_config('DEFAULT/logging_context_format_string').with_value( diff --git a/cinder/spec/classes/cinder_spec.rb b/cinder/spec/classes/cinder_spec.rb index 093948d0f..8695d144b 100644 --- a/cinder/spec/classes/cinder_spec.rb +++ b/cinder/spec/classes/cinder_spec.rb @@ -17,6 +17,7 @@ req_params end + it { is_expected.to contain_class('cinder::logging') } it { is_expected.to contain_class('cinder::params') } it { is_expected.to contain_class('mysql::bindings::python') } @@ -32,13 +33,9 @@ is_expected.to contain_cinder_config('oslo_messaging_rabbit/heartbeat_timeout_threshold').with_value('0') is_expected.to contain_cinder_config('oslo_messaging_rabbit/heartbeat_rate').with_value('2') is_expected.to contain_cinder_config('oslo_messaging_rabbit/rabbit_userid').with(:value => 'guest') - is_expected.to contain_cinder_config('DEFAULT/verbose').with(:value => false) - is_expected.to contain_cinder_config('DEFAULT/debug').with(:value => false) - is_expected.to contain_cinder_config('DEFAULT/use_stderr').with(:value => true) is_expected.to contain_cinder_config('DEFAULT/storage_availability_zone').with(:value => 'nova') is_expected.to contain_cinder_config('DEFAULT/default_availability_zone').with(:value => 'nova') is_expected.to contain_cinder_config('DEFAULT/api_paste_config').with(:value => '/etc/cinder/api-paste.ini') - is_expected.to contain_cinder_config('DEFAULT/log_dir').with(:value => '') is_expected.to contain_cinder_config('DEFAULT/lock_path').with(:value => '/var/lock/cinder') end @@ -200,37 +197,6 @@ end end - describe 'with syslog disabled' do - let :params do - req_params - end - - it { is_expected.to contain_cinder_config('DEFAULT/use_syslog').with_value(false) } - end - - describe 'with syslog enabled' do - let :params do - req_params.merge({ - :use_syslog => 'true', - }) - end - - it { is_expected.to contain_cinder_config('DEFAULT/use_syslog').with_value(true) } - it { is_expected.to contain_cinder_config('DEFAULT/syslog_log_facility').with_value('LOG_USER') } - end - - describe 'with syslog enabled and custom settings' do - let :params do - req_params.merge({ - :use_syslog => 'true', - :log_facility => 'LOG_LOCAL0' - }) - end - - it { is_expected.to contain_cinder_config('DEFAULT/use_syslog').with_value(true) } - it { is_expected.to contain_cinder_config('DEFAULT/syslog_log_facility').with_value('LOG_LOCAL0') } - end - describe 'with different lock_path' do let(:params) { req_params.merge!({:lock_path => '/var/run/cinder.locks'}) } it { is_expected.to contain_cinder_config('DEFAULT/lock_path').with_value('/var/run/cinder.locks') } diff --git a/firewall/manifests/linux/redhat.pp b/firewall/manifests/linux/redhat.pp index 9e5ad18e2..3144ae7a9 100644 --- a/firewall/manifests/linux/redhat.pp +++ b/firewall/manifests/linux/redhat.pp @@ -63,7 +63,7 @@ #lint:ignore:quoted_booleans 'true',true: { case $::operatingsystemrelease { - /^7.*/: { $seluser = 'unconfined_u' } + /^(6|7)\..*/: { $seluser = 'unconfined_u' } default: { $seluser = 'system_u' } } } diff --git a/glance/manifests/api.pp b/glance/manifests/api.pp index e261d864e..b944ccfe7 100644 --- a/glance/manifests/api.pp +++ b/glance/manifests/api.pp @@ -154,9 +154,6 @@ # (optional) CA certificate file to use to verify connecting clients # Defaults to false, not set # -# [*mysql_module*] -# (optional) Deprecated. Does nothing. -# # [*known_stores*] # (optional)List of which store classes and store class locations are # currently known to glance at startup. @@ -229,7 +226,6 @@ $validate = false, $validation_options = {}, # DEPRECATED PARAMETERS - $mysql_module = undef, $auth_host = '127.0.0.1', $auth_url = 'http://localhost:5000/v2.0', $auth_port = '35357', @@ -241,10 +237,6 @@ include ::glance::api::logging require keystone::python - if $mysql_module { - warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') - } - if ( $glance::params::api_package_name != $glance::params::registry_package_name ) { ensure_packages('glance-api', { diff --git a/glance/manifests/db/mysql.pp b/glance/manifests/db/mysql.pp index f0b2090ad..59170a4d4 100644 --- a/glance/manifests/db/mysql.pp +++ b/glance/manifests/db/mysql.pp @@ -26,9 +26,6 @@ # [*collate*] # the database collation. Optional. Defaults to 'utf8_general_ci' # -# [*mysql_module*] -# (optional) Deprecated. Does nothing. -# # === Deprecated parameters: # # [*cluster_id*] This parameter does nothing @@ -42,13 +39,8 @@ $charset = 'utf8', $collate = 'utf8_general_ci', $cluster_id = 'localzone', - $mysql_module = undef, ) { - if $mysql_module { - warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') - } - validate_string($password) ::openstacklib::db::mysql { 'glance': diff --git a/glance/manifests/registry.pp b/glance/manifests/registry.pp index 812244a9a..220ee1ab6 100644 --- a/glance/manifests/registry.pp +++ b/glance/manifests/registry.pp @@ -128,9 +128,6 @@ # (Optional) Run db sync on the node. # Defaults to true # -# [*mysql_module*] -# (optional) Deprecated. Does nothing. -# class glance::registry( $keystone_password, $package_ensure = 'present', @@ -160,7 +157,6 @@ $ca_file = false, $sync_db = true, # DEPRECATED PARAMETERS - $mysql_module = undef, $auth_host = '127.0.0.1', $auth_port = '35357', $auth_admin_prefix = false, @@ -170,10 +166,6 @@ include ::glance::registry::logging require keystone::python - if $mysql_module { - warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') - } - if ( $glance::params::api_package_name != $glance::params::registry_package_name ) { ensure_packages( 'glance-registry', { diff --git a/haproxy/manifests/peer.pp b/haproxy/manifests/peer.pp index d53b19a81..7295aaed0 100644 --- a/haproxy/manifests/peer.pp +++ b/haproxy/manifests/peer.pp @@ -1,7 +1,7 @@ # == Define Resource 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 +# 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 @@ -45,7 +45,7 @@ concat::fragment { "peers-${peers_name}-${name}": ensure => $ensure, order => "30-peers-01-${peers_name}-${name}", - target => '/etc/haproxy/haproxy.cfg', + target => $::haproxy::config_file, content => template('haproxy/haproxy_peer.erb'), } } diff --git a/haproxy/manifests/peers.pp b/haproxy/manifests/peers.pp index 037045842..f431aebfd 100644 --- a/haproxy/manifests/peers.pp +++ b/haproxy/manifests/peers.pp @@ -1,6 +1,6 @@ # == Defined Type: haproxy::peers # -# This type will set up a peers entry in /etc/haproxy/haproxy.cfg +# This type will set up a peers entry in haproxy.cfg # on the load balancer. This setting is required to share the # current state of HAproxy with other HAproxy in High available # configurations. @@ -19,7 +19,7 @@ # Template uses: $name, $ipaddress, $ports, $options concat::fragment { "${name}_peers_block": order => "30-peers-00-${name}", - target => '/etc/haproxy/haproxy.cfg', + target => $::haproxy::config_file, content => template('haproxy/haproxy_peers_block.erb'), } diff --git a/haproxy/spec/classes/haproxy_spec.rb b/haproxy/spec/classes/haproxy_spec.rb index ab0d79dab..37bcf8e18 100644 --- a/haproxy/spec/classes/haproxy_spec.rb +++ b/haproxy/spec/classes/haproxy_spec.rb @@ -109,6 +109,23 @@ end end end + context "on #{osfamily} family operatingsystems with setting haproxy.cfg location" do + let(:facts) do + { :osfamily => osfamily }.merge default_facts + end + let(:params) do + { + 'config_file' => '/tmp/haproxy.cfg', + } + end + it 'should set up /tmp/haproxy.cfg as a concat resource' do + subject.should contain_concat('/tmp/haproxy.cfg').with( + 'owner' => '0', + 'group' => '0', + 'mode' => '0644' + ) + end + end context "on #{osfamily} family operatingsystems without managing the service" do let(:facts) do { :osfamily => osfamily }.merge default_facts diff --git a/haproxy/spec/defines/peer_spec.rb b/haproxy/spec/defines/peer_spec.rb index 677e0b56c..e3cc1f91d 100644 --- a/haproxy/spec/defines/peer_spec.rb +++ b/haproxy/spec/defines/peer_spec.rb @@ -1,12 +1,19 @@ require 'spec_helper' describe 'haproxy::peer' do + let :pre_condition do + 'class{"haproxy": + config_file => "/tmp/haproxy.cfg" + } + ' + end let(:title) { 'dero' } let(:facts) do { :ipaddress => '1.1.1.1', :hostname => 'dero', :concat_basedir => '/foo', + :osfamily => 'RedHat', } end @@ -20,7 +27,7 @@ it { should contain_concat__fragment('peers-tyler-dero').with( 'order' => '30-peers-01-tyler-dero', - 'target' => '/etc/haproxy/haproxy.cfg', + 'target' => '/tmp/haproxy.cfg', 'content' => " peer dero 1.1.1.1:1024\n" ) } end diff --git a/haproxy/spec/defines/peers_spec.rb b/haproxy/spec/defines/peers_spec.rb index 95b768a68..9e6113f2c 100644 --- a/haproxy/spec/defines/peers_spec.rb +++ b/haproxy/spec/defines/peers_spec.rb @@ -1,9 +1,16 @@ require 'spec_helper' describe 'haproxy::peers' do + let :pre_condition do + 'class{"haproxy": + config_file => "/tmp/haproxy.cfg" + } + ' + end let(:facts) {{ :ipaddress => '1.1.1.1', :concat_basedir => '/foo', + :osfamily => 'RedHat', }} context "when no options are passed" do @@ -11,7 +18,7 @@ it { should contain_concat__fragment('bar_peers_block').with( 'order' => '30-peers-00-bar', - 'target' => '/etc/haproxy/haproxy.cfg', + 'target' => '/tmp/haproxy.cfg', 'content' => "\npeers bar\n" ) } end diff --git a/heat/manifests/keystone/domain.pp b/heat/manifests/keystone/domain.pp index 841556373..3d7750e32 100644 --- a/heat/manifests/keystone/domain.pp +++ b/heat/manifests/keystone/domain.pp @@ -79,7 +79,7 @@ 'password' => $domain_password, 'domain' => $domain_name, }) - ensure_resource('keystone_user_role', "${domain_admin}@::${domain_name}", { + ensure_resource('keystone_user_role', "${domain_admin}::${domain_name}@::${domain_name}", { 'roles' => ['admin'], }) diff --git a/heat/spec/classes/heat_keystone_domain_spec.rb b/heat/spec/classes/heat_keystone_domain_spec.rb index 096300a6a..c87abb5b0 100644 --- a/heat/spec/classes/heat_keystone_domain_spec.rb +++ b/heat/spec/classes/heat_keystone_domain_spec.rb @@ -33,7 +33,7 @@ :password => params[:domain_password], :domain => params[:domain_name], ) - is_expected.to contain_keystone_user_role('heat_admin@::heat').with( + is_expected.to contain_keystone_user_role('heat_admin::heat@::heat').with( :roles => ['admin'], ) end diff --git a/ironic/manifests/init.pp b/ironic/manifests/init.pp index bed1afe24..c38c75497 100644 --- a/ironic/manifests/init.pp +++ b/ironic/manifests/init.pp @@ -52,7 +52,7 @@ # # [*rpc_backend*] # (optional) what rpc/queuing service to use -# Defaults to impl_kombu (rabbitmq) +# Defaults to rabbit (rabbitmq) # # [*rabbit_host*] # (Optional) IP or hostname of the rabbit server. @@ -200,7 +200,7 @@ $auth_strategy = 'keystone', $enabled_drivers = ['pxe_ipmitool'], $control_exchange = 'openstack', - $rpc_backend = 'ironic.openstack.common.rpc.impl_kombu', + $rpc_backend = 'rabbit', $rabbit_hosts = false, $rabbit_virtual_host = '/', $rabbit_host = 'localhost', @@ -323,7 +323,7 @@ include ::ironic::db::sync } - if $rpc_backend == 'ironic.openstack.common.rpc.impl_kombu' { + if $rpc_backend == 'ironic.openstack.common.rpc.impl_kombu' or $rpc_backend == 'rabbit' { if ! $rabbit_password { fail('When rpc_backend is rabbitmq, you must set rabbit password') @@ -380,7 +380,7 @@ } } - if $rpc_backend == 'ironic.openstack.common.rpc.impl_qpid' { + if $rpc_backend == 'ironic.openstack.common.rpc.impl_qpid' or $rpc_backend == 'qpid' { ironic_config { 'DEFAULT/qpid_hostname': value => $qpid_hostname; 'DEFAULT/qpid_port': value => $qpid_port; diff --git a/keystone/lib/puppet/provider/keystone.rb b/keystone/lib/puppet/provider/keystone.rb index 64f46de50..a3b193aac 100644 --- a/keystone/lib/puppet/provider/keystone.rb +++ b/keystone/lib/puppet/provider/keystone.rb @@ -65,6 +65,26 @@ def self.domain_name_from_id(id) @domain_hash[id] end + def self.fetch_domain(domain) + request('domain', 'show', domain) + rescue Puppet::ExecutionFailure => e + raise e unless e.message =~ /No domain with a name or ID/ + end + + def self.fetch_project(name, domain) + domain ||= default_domain + request('project', 'show', [name, '--domain', domain]) + rescue Puppet::ExecutionFailure => e + raise e unless e.message =~ /No project with a name or ID/ + end + + def self.fetch_user(name, domain) + domain ||= default_domain + request('user', 'show', [name, '--domain', domain]) + rescue Puppet::ExecutionFailure => e + raise e unless e.message =~ /No user with a name or ID/ + end + def self.get_admin_endpoint endpoint = nil if keystone_file @@ -169,6 +189,22 @@ def self.service_url @service_url ||= get_service_url end + def self.set_domain_for_name(name, domain_name) + if domain_name.nil? || domain_name.empty? + raise(Puppet::Error, "Missing domain name for resource #{name}") + end + domain = fetch_domain(domain_name) + domain_id = domain ? domain[:id] : nil + case domain_id + when default_domain_id + name + when nil + name + else + name << "::#{domain_name}" + end + end + def self.ssl? if keystone_file && keystone_file['ssl'] && keystone_file['ssl']['enable'] && keystone_file['ssl']['enable'].strip.downcase == 'true' return true diff --git a/keystone/lib/puppet/provider/keystone_tenant/openstack.rb b/keystone/lib/puppet/provider/keystone_tenant/openstack.rb index ac1dfb107..b47832d33 100644 --- a/keystone/lib/puppet/provider/keystone_tenant/openstack.rb +++ b/keystone/lib/puppet/provider/keystone_tenant/openstack.rb @@ -70,37 +70,16 @@ def id end def self.instances - instance_hash = {} - list = request('project', 'list', '--long') - list.each do |project| - domname = domain_name_from_id(project[:domain_id]) - if instance_hash.include?(project[:name]) # not unique - curdomid = instance_hash[project[:name]][:domain_id] - if curdomid != default_domain_id - # Move the project from the short name slot to the long name slot - # because it is not in the default domain. - curdomname = domain_name_from_id(curdomid) - instance_hash["#{project[:name]}::#{curdomname}"] = instance_hash[project[:name]] - # Use the short name slot for the new project - instance_hash[project[:name]] = project - else - # Use the long name for the new project - instance_hash["#{project[:name]}::#{domname}"] = project - end - else - # Unique (for now) - store in short name slot - instance_hash[project[:name]] = project - end - end - instance_hash.keys.collect do |project_name| - project = instance_hash[project_name] - domname = domain_name_from_id(project[:domain_id]) + projects = request('project', 'list', '--long') + projects.collect do |project| + domain_name = domain_name_from_id(project[:domain_id]) + project_name = set_domain_for_name(project[:name], domain_name) new( :name => project_name, :ensure => :present, :enabled => project[:enabled].downcase.chomp == 'true' ? true : false, :description => project[:description], - :domain => domname, + :domain => domain_name, :domain_id => project[:domain_id], :id => project[:id] ) @@ -139,5 +118,4 @@ def flush @property_flush.clear end end - end diff --git a/keystone/lib/puppet/provider/keystone_user/openstack.rb b/keystone/lib/puppet/provider/keystone_user/openstack.rb index 588f2447b..621203820 100644 --- a/keystone/lib/puppet/provider/keystone_user/openstack.rb +++ b/keystone/lib/puppet/provider/keystone_user/openstack.rb @@ -36,11 +36,11 @@ def create @property_hash = self.class.request('user', 'create', properties) @property_hash[:name] = resource[:name] @property_hash[:domain] = user_domain + if resource[:tenant] # DEPRECATED - To be removed in next release (Liberty) # https://bugs.launchpad.net/puppet-keystone/+bug/1472437 - project_id = Puppet::Resource.indirection.find("Keystone_tenant/#{resource[:tenant]}")[:id] - set_project(resource[:tenant], project_id) + set_project(resource[:tenant]) @property_hash[:tenant] = resource[:tenant] end @property_hash[:ensure] = :present @@ -158,11 +158,17 @@ def find_project_for_user(projname, project_id = nil) return nil end - def set_project(newproject, project_id = nil) + def set_project(name) # DEPRECATED - To be removed in next release (Liberty) # https://bugs.launchpad.net/puppet-keystone/+bug/1472437 + project_name, domain_name = self.class.name_and_domain(name) + project = self.class.fetch_project(project_name, domain_name) + project_id = project ? project[:id] : nil unless project_id - project_id = Puppet::Resource.indirection.find("Keystone_tenant/#{newproject}")[:id] + raise(Puppet::Error, "No project found for name #{name} and domain #{domain}") + end + if project_id == :absent + raise(Puppet::Error, "Project #{newproject} missing when creating user #{resource[:name]}") end # Currently the only way to assign a user to a tenant not using user-create # is to use role-add - this means we also need a role - there is usual @@ -178,13 +184,13 @@ def set_project(newproject, project_id = nil) end # finally, assign the user to the project with the role self.class.request('role', 'add', [default_role, '--project', project_id, '--user', id]) - newproject + name end # DEPRECATED - To be removed in next release (Liberty) # https://bugs.launchpad.net/puppet-keystone/+bug/1472437 def tenant=(value) - @property_hash[:tenant] = set_project(value) + @property_hash[:tenant] = set_project(resource[:tenant]) end # DEPRECATED - To be removed in next release (Liberty) @@ -202,8 +208,10 @@ def tenant if tenant_name.nil? or tenant_name.empty? return nil # nothing found, nothing given end - project_id = Puppet::Resource.indirection.find("Keystone_tenant/#{tenant_name}")[:id] - find_project_for_user(tenant_name, project_id) + project_name, domain_name = self.class.name_and_domain(tenant_name) + project = self.class.fetch_project(project_name, domain_name) + project_id = project ? project[:id] : nil + find_project_for_user(tenant_name, project_id) end def domain @@ -215,30 +223,10 @@ def domain_id end def self.instances - instance_hash = {} - request('user', 'list', ['--long']).each do |user| - # The field says "domain" but it is really the domain_id - domname = domain_name_from_id(user[:domain]) - if instance_hash.include?(user[:name]) # not unique - curdomid = instance_hash[user[:name]][:domain] - if curdomid != default_domain_id - # Move the user from the short name slot to the long name slot - # because it is not in the default domain. - curdomname = domain_name_from_id(curdomid) - instance_hash["#{user[:name]}::#{curdomname}"] = instance_hash[user[:name]] - # Use the short name slot for the new user - instance_hash[user[:name]] = user - else - # Use the long name for the new user - instance_hash["#{user[:name]}::#{domname}"] = user - end - else - # Unique (for now) - store in short name slot - instance_hash[user[:name]] = user - end - end - instance_hash.keys.collect do |user_name| - user = instance_hash[user_name] + users = request('user', 'list', ['--long']) + users.collect do |user| + domain_name = domain_name_from_id(user[:domain]) + user_name = set_domain_for_name(user[:name], domain_name) new( :name => user_name, :ensure => :present, @@ -246,7 +234,7 @@ def self.instances :password => user[:password], :email => user[:email], :description => user[:description], - :domain => domain_name_from_id(user[:domain]), + :domain => domain_name, :domain_id => user[:domain], :id => user[:id] ) diff --git a/keystone/lib/puppet/provider/keystone_user_role/openstack.rb b/keystone/lib/puppet/provider/keystone_user_role/openstack.rb index e670a6750..89d74c486 100644 --- a/keystone/lib/puppet/provider/keystone_user_role/openstack.rb +++ b/keystone/lib/puppet/provider/keystone_user_role/openstack.rb @@ -17,16 +17,18 @@ def initialize(value={}) def create if resource[:roles] + options = properties resource[:roles].each do |role| - self.class.request('role', 'add', [role] + properties) + self.class.request('role', 'add', [role] + options) end end end def destroy if @property_hash[:roles] + options = properties @property_hash[:roles].each do |role| - self.class.request('role', 'remove', [role] + properties) + self.class.request('role', 'remove', [role] + options) end end @property_hash[:ensure] = :absent @@ -89,7 +91,7 @@ def properties elsif get_domain properties << '--domain' << get_domain else - error("No project or domain specified for role") + raise(Puppet::Error, 'No project or domain specified for role') end properties << '--user' << get_user_id properties @@ -118,17 +120,33 @@ def get_domain end def get_user_id - @user_id ||= Puppet::Resource.indirection.find("Keystone_user/#{get_user}")[:id] + return @user_id if defined?(@user_id) + user_name, domain_name = Util.split_domain(get_user) + if user_name.nil? + @user_id = nil + else + user = self.class.fetch_user(user_name, domain_name) + if user.nil? + raise(Puppet::Error, "No user #{user_name} with domain #{domain_name} found") + else + @user_id = user[:id] + end + end + @user_id end def get_project_id - # use defined because @project_id may be nil return @project_id if defined?(@project_id) - projname, domname = Util.split_domain(get_project) - if projname.nil? + project_name, domain_name = Util.split_domain(get_project) + if project_name.nil? @project_id = nil else - @project_id ||= Puppet::Resource.indirection.find("Keystone_tenant/#{get_project}")[:id] + project = self.class.fetch_project(project_name, domain_name) + if project.nil? + raise(Puppet::Error, "No project #{project_name} with domain #{domain_name} found") + else + @project_id = project[:id] + end end @project_id end diff --git a/keystone/spec/acceptance/basic_keystone_spec.rb b/keystone/spec/acceptance/basic_keystone_spec.rb index 5694c3898..e3593c2d8 100644 --- a/keystone/spec/acceptance/basic_keystone_spec.rb +++ b/keystone/spec/acceptance/basic_keystone_spec.rb @@ -99,38 +99,35 @@ class { '::keystone::endpoint': enabled => true, description => 'Domain for admin v3 users', } - keystone_tenant { 'servicesv3': + keystone_tenant { 'servicesv3::service_domain': ensure => present, enabled => true, description => 'Tenant for the openstack services', - domain => 'service_domain', } - keystone_tenant { 'openstackv3': + keystone_tenant { 'openstackv3::admin_domain': ensure => present, enabled => true, description => 'admin tenant', - domain => 'admin_domain', } - keystone_user { 'adminv3': + keystone_user { 'adminv3::admin_domain': ensure => present, enabled => true, - tenant => 'openstackv3', # note: don't have to use 'openstackv3::admin_domain' here since the tenant name 'openstackv3' is unique among all domains + tenant => 'openstackv3::admin_domain', email => 'test@example.tld', password => 'a_big_secret', - domain => 'admin_domain', } - keystone_user_role { 'adminv3@openstackv3': + keystone_user_role { 'adminv3::admin_domain@openstackv3::admin_domain': ensure => present, roles => ['admin'], } # service user exists only in the service_domain - must # use v3 api - ::keystone::resource::service_identity { 'beaker-civ3': + ::keystone::resource::service_identity { 'beaker-civ3::service_domain': service_type => 'beakerv3', service_description => 'beakerv3 service', service_name => 'beakerv3', password => 'secret', - tenant => 'servicesv3', + tenant => 'servicesv3::service_domain', public_url => 'http://127.0.0.1:1234/v3', admin_url => 'http://127.0.0.1:1234/v3', internal_url => 'http://127.0.0.1:1234/v3', diff --git a/keystone/spec/acceptance/keystone_federation_identity_provider_spec.rb b/keystone/spec/acceptance/keystone_federation_identity_provider_spec.rb index 2dbdf6c90..aac98888d 100644 --- a/keystone/spec/acceptance/keystone_federation_identity_provider_spec.rb +++ b/keystone/spec/acceptance/keystone_federation_identity_provider_spec.rb @@ -12,25 +12,29 @@ case $::osfamily { 'Debian': { include ::apt - apt::ppa { 'ppa:ubuntu-cloud-archive/liberty-staging': - # it's false by default in 2.x series but true in 1.8.x - package_manage => false, + class { '::openstack_extras::repo::debian::ubuntu': + release => 'liberty', + repo => 'proposed', + package_require => true, } - Exec['apt_update'] -> Package<||> } 'RedHat': { class { '::openstack_extras::repo::redhat::redhat': manage_rdo => false, repo_hash => { - # we need kilo repo to be installed for dependencies - 'rdo-kilo' => { - 'baseurl' => 'https://repos.fedorapeople.org/repos/openstack/openstack-kilo/el7/', - 'descr' => 'RDO kilo', + 'openstack-common-testing' => { + 'baseurl' => 'http://cbs.centos.org/repos/cloud7-openstack-common-testing/x86_64/os/', + 'descr' => 'openstack-common-testing', 'gpgcheck' => 'no', }, - 'rdo-liberty' => { - 'baseurl' => 'http://trunk.rdoproject.org/centos7/current/', - 'descr' => 'RDO trunk', + 'openstack-liberty-testing' => { + 'baseurl' => 'http://cbs.centos.org/repos/cloud7-openstack-liberty-testing/x86_64/os/', + 'descr' => 'openstack-liberty-testing', + 'gpgcheck' => 'no', + }, + 'openstack-liberty-trunk' => { + 'baseurl' => 'http://trunk.rdoproject.org/centos7-liberty/current-passed-ci/', + 'descr' => 'openstack-liberty-trunk', 'gpgcheck' => 'no', }, }, @@ -95,38 +99,35 @@ class { '::keystone::endpoint': enabled => true, description => 'Domain for admin v3 users', } - keystone_tenant { 'servicesv3': + keystone_tenant { 'servicesv3::service_domain': ensure => present, enabled => true, description => 'Tenant for the openstack services', - domain => 'service_domain', } - keystone_tenant { 'openstackv3': + keystone_tenant { 'openstackv3::admin_domain': ensure => present, enabled => true, description => 'admin tenant', - domain => 'admin_domain', } - keystone_user { 'adminv3': + keystone_user { 'adminv3::admin_domain': ensure => present, enabled => true, - tenant => 'openstackv3', # note: don't have to use 'openstackv3::admin_domain' here since the tenant name 'openstackv3' is unique among all domains + tenant => 'openstackv3::admin_domain', email => 'test@example.tld', password => 'a_big_secret', - domain => 'admin_domain', } - keystone_user_role { 'adminv3@openstackv3': + keystone_user_role { 'adminv3::admin_domain@openstackv3::admin_domain': ensure => present, roles => ['admin'], } # service user exists only in the service_domain - must # use v3 api - ::keystone::resource::service_identity { 'beaker-civ3': + ::keystone::resource::service_identity { 'beaker-civ3::service_domain': service_type => 'beakerv3', service_description => 'beakerv3 service', service_name => 'beakerv3', password => 'secret', - tenant => 'servicesv3', + tenant => 'servicesv3::service_domain', public_url => 'http://127.0.0.1:1234/v3', admin_url => 'http://127.0.0.1:1234/v3', internal_url => 'http://127.0.0.1:1234/v3', diff --git a/keystone/spec/acceptance/keystone_wsgi_apache_spec.rb b/keystone/spec/acceptance/keystone_wsgi_apache_spec.rb index 0a4eca7b8..136614d9c 100644 --- a/keystone/spec/acceptance/keystone_wsgi_apache_spec.rb +++ b/keystone/spec/acceptance/keystone_wsgi_apache_spec.rb @@ -98,38 +98,35 @@ class { '::keystone::endpoint': enabled => true, description => 'Domain for admin v3 users', } - keystone_tenant { 'servicesv3': + keystone_tenant { 'servicesv3::service_domain': ensure => present, enabled => true, description => 'Tenant for the openstack services', - domain => 'service_domain', } - keystone_tenant { 'openstackv3': + keystone_tenant { 'openstackv3::admin_domain': ensure => present, enabled => true, description => 'admin tenant', - domain => 'admin_domain', } - keystone_user { 'adminv3': + keystone_user { 'adminv3::admin_domain': ensure => present, enabled => true, - tenant => 'openstackv3', # note: don't have to use 'openstackv3::admin_domain' here since the tenant name 'openstackv3' is unique among all domains + tenant => 'openstackv3::admin_domain', email => 'test@example.tld', password => 'a_big_secret', - domain => 'admin_domain', } - keystone_user_role { 'adminv3@openstackv3': + keystone_user_role { 'adminv3::admin_domain@openstackv3::admin_domain': ensure => present, roles => ['admin'], } # service user exists only in the service_domain - must # use v3 api - ::keystone::resource::service_identity { 'beaker-civ3': + ::keystone::resource::service_identity { 'beaker-civ3::service_domain': service_type => 'beakerv3', service_description => 'beakerv3 service', service_name => 'beakerv3', password => 'secret', - tenant => 'servicesv3', + tenant => 'servicesv3::service_domain', public_url => 'http://127.0.0.1:1234/v3', admin_url => 'http://127.0.0.1:1234/v3', internal_url => 'http://127.0.0.1:1234/v3', diff --git a/keystone/spec/unit/provider/keystone_spec.rb b/keystone/spec/unit/provider/keystone_spec.rb index 5e133cd73..f7f420f4e 100644 --- a/keystone/spec/unit/provider/keystone_spec.rb +++ b/keystone/spec/unit/provider/keystone_spec.rb @@ -12,6 +12,12 @@ class Puppet::Provider::Keystone end describe Puppet::Provider::Keystone do + let(:set_env) do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' + end let(:another_class) do class AnotherKlass < Puppet::Provider::Keystone @@ -20,11 +26,32 @@ class AnotherKlass < Puppet::Provider::Keystone AnotherKlass end + before(:each) { set_env } + after :each do klass.reset another_class.reset end + describe '#fetch_domain' do + it 'should be false if the domain does not exist' do + klass.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'no_domain') + .raises(Puppet::ExecutionFailure, "Execution of '/usr/bin/openstack domain show --format shell no_domain' returned 1: No domain with a name or ID of 'no_domain' exists.") + expect(klass.fetch_domain('no_domain')).to be_falsey + end + + it 'should return the domain' do + klass.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'The Domain') + .returns(' +name="The Domain" +id="the_domain_id" +') + expect(klass.fetch_domain('The Domain')).to eq({:name=>"The Domain", :id=>"the_domain_id"}) + end + end + describe '#ssl?' do it 'should be false if there is no keystone file' do File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(false) @@ -56,6 +83,66 @@ class AnotherKlass < Puppet::Provider::Keystone end end + describe '#fetch_project' do + let(:set_env) do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' + end + + before(:each) do + set_env + end + + it 'should be false if the project does not exist' do + klass.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['no_project', '--domain', 'Default']) + .raises(Puppet::ExecutionFailure, "Execution of '/usr/bin/openstack project show --format shell no_project' returned 1: No project with a name or ID of 'no_project' exists.") + expect(klass.fetch_project('no_project', 'Default')).to be_falsey + end + + it 'should return the project' do + klass.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['The Project', '--domain', 'Default']) + .returns(' +name="The Project" +id="the_project_id" +') + expect(klass.fetch_project('The Project', 'Default')).to eq({:name=>"The Project", :id=>"the_project_id"}) + end + end + + describe '#fetch_user' do + let(:set_env) do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' + end + + before(:each) do + set_env + end + + it 'should be false if the user does not exist' do + klass.expects(:openstack) + .with('user', 'show', '--format', 'shell', ['no_user', '--domain', 'Default']) + .raises(Puppet::ExecutionFailure, "Execution of '/usr/bin/openstack user show --format shell no_user' returned 1: No user with a name or ID of 'no_user' exists.") + expect(klass.fetch_user('no_user', 'Default')).to be_falsey + end + + it 'should return the user' do + klass.expects(:openstack) + .with('user', 'show', '--format', 'shell', ['The User', '--domain', 'Default']) + .returns(' +name="The User" +id="the_user_id" +') + expect(klass.fetch_user('The User', 'Default')).to eq({:name=>"The User", :id=>"the_user_id"}) + end + end + describe '#get_admin_endpoint' do it 'should return nothing if there is no keystone config file' do expect(klass.get_admin_endpoint).to be_nil @@ -168,6 +255,47 @@ class AnotherKlass < Puppet::Provider::Keystone end end + describe '#set_domain_for_name' do + it 'should raise an error if the domain is not provided' do + expect do + klass.set_domain_for_name('name', nil) + end.to raise_error(Puppet::Error, /Missing domain name for resource/) + end + + it 'should return the name only when the provided domain is the default domain id' do + klass.expects(:default_domain_id) + .returns('default') + klass.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'Default') + .returns(' +name="Default" +id="default" +') + expect(klass.set_domain_for_name('name', 'Default')).to eq('name') + end + + it 'should return the name and domain when the provided domain is not the default domain id' do + klass.expects(:default_domain_id) + .returns('default') + klass.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'Other Domain') + .returns(' +name="Other Domain" +id="other_domain_id" +') + expect(klass.set_domain_for_name('name', 'Other Domain')).to eq('name::Other Domain') + end + + it 'should return the name only if the domain cannot be fetched' do + klass.expects(:default_domain_id) + .returns('default') + klass.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'Unknown Domain') + .returns('') + expect(klass.set_domain_for_name('name', 'Unknown Domain')).to eq('name') + end + end + describe 'when retrieving the security token' do it 'should return nothing if there is no keystone config file' do File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(false) @@ -200,13 +328,6 @@ class AnotherKlass < Puppet::Provider::Keystone end describe 'when using domains' do - let(:set_env) do - ENV['OS_USERNAME'] = 'test' - ENV['OS_PASSWORD'] = 'abc123' - ENV['OS_PROJECT_NAME'] = 'test' - ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' - end - before(:each) do set_env end diff --git a/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb b/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb index 0fddeca60..639fb392e 100644 --- a/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_tenant/openstack_spec.rb @@ -106,12 +106,25 @@ def before_hook(domainlist) .returns('"ID","Name","Domain ID","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True "2cb05cfed7c24279be884ba4f6520262","foo","bar_domain_id","foo",True -' - ) +') + provider.class.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'foo_domain') + .returns('description="" +enabled="True" +id="foo_domain_id" +name="foo_domain" +') + provider.class.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'bar_domain') + .returns('description="" +enabled="True" +id="bar_domain_id" +name="bar_domain" +') instances = provider.class.instances - expect(instances[0].name).to eq('foo') - expect(instances[0].domain).to eq('bar_domain') - expect(instances[1].name).to eq('foo::foo_domain') + expect(instances[0].name).to eq('foo::foo_domain') + expect(instances[0].domain).to eq('foo_domain') + expect(instances[1].name).to eq('foo::bar_domain') end end end diff --git a/keystone/spec/unit/provider/keystone_user/openstack_spec.rb b/keystone/spec/unit/provider/keystone_user/openstack_spec.rb index db37d5a0b..1e4cd658e 100644 --- a/keystone/spec/unit/provider/keystone_user/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_user/openstack_spec.rb @@ -27,13 +27,13 @@ def project_class let(:user_attrs) do { - :name => 'foo', - :ensure => :present, - :enabled => 'True', - :password => 'foo', - :tenant => 'foo', - :email => 'foo@example.com', - :domain => 'foo_domain', + :name => 'user1', + :ensure => :present, + :enabled => 'True', + :password => 'secret', + :tenant => 'project2::domain2', + :email => 'user1@example.com', + :domain => 'domain1', } end @@ -45,118 +45,29 @@ def project_class provider_class.new(resource) end - def before_hook(delete, missing, noproject, user_cached, project_only) - set_env - unless noproject - project_class.expects(:openstack).once - .with('domain', 'list', '--quiet', '--format', 'csv', []) - .returns('"ID","Name","Enabled","Description" -"default","Default",True,"default" -"foo_domain_id","foo_domain",True,"foo domain" -"bar_domain_id","bar_domain",True,"bar domain" -"another_domain_id","another_domain",True,"another domain" -"disabled_domain_id","disabled_domain",False,"disabled domain" -' - ) - end - - if project_only - return - end - - provider.class.expects(:openstack).once - .with('domain', 'list', '--quiet', '--format', 'csv', []) - .returns('"ID","Name","Enabled","Description" -"default","Default",True,"default" -"foo_domain_id","foo_domain",True,"foo domain" -"bar_domain_id","bar_domain",True,"bar domain" -"another_domain_id","another_domain",True,"another domain" -"disabled_domain_id","disabled_domain",False,"disabled domain" -' - ) - if user_cached - return # using cached user, so no user list - end - if noproject - project = '' - else - project = 'foo' - end - # delete will call the search again and should not return the deleted user - foo_returns = ['"ID","Name","Project Id","Domain","Description","Email","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo",' + project + ',"foo_domain_id","foo description","foo@example.com",True -"2cb05cfed7c24279be884ba4f6520262","foo",' + project + ',"bar_domain_id","foo description","foo@example.com",True -"3cb05cfed7c24279be884ba4f6520262","foo",' + project + ',"another_domain_id","foo description","foo@example.com",True -' - ] - nn = 1 - if delete - nn = 2 - foo_returns << '' - end - if missing - foo_returns = [''] - end - provider.class.expects(:openstack).times(nn) - .with('user', 'list', '--quiet', '--format', 'csv', ['--long']) - .returns(*foo_returns) - end - - before :each, :default => true do - before_hook(false, false, false, false, false) - end - before :each, :delete => true do - before_hook(true, false, false, false, false) - end - before :each, :missing => true do - before_hook(false, true, false, false, false) - end - before :each, :noproject => true do - before_hook(false, false, true, false, false) - end - before :each, :default_https => true do - before_hook(false, false, false, false, false) - end - before :each, :user_cached => true do - before_hook(false, false, false, true, false) - end - before :each, :nohooks => true do - set_env - end - before :each, :project_only => true do - before_hook(false, false, false, false, true) - end - before :each, :noproject_user_cached => true do - before_hook(false, false, true, true, false) - end + before(:each) { set_env } describe 'when managing a user' do - describe '#create', :project_only => true do + describe '#create' do it 'creates a user' do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","foo","bar_domain_id","foo",True -' - ) provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') - .returns(' -name="_member_" -' - ) + .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '2cb05cfed7c24279be884ba4f6520262', '--user', '12b23f07d4a3448d8189521ab09610b0']) + .with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'foo_domain']) - .returns('email="foo@example.com" + .with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1']) + .returns('email="user1@example.com" enabled="True" -id="12b23f07d4a3448d8189521ab09610b0" -name="foo" -username="foo" -' - ) +id="user1_id" +name="user1" +username="user1" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') provider.create expect(provider.exists?).to be_truthy end @@ -170,7 +81,6 @@ def before_hook(delete, missing, noproject, user_cached, project_only) provider.destroy expect(provider.exists?).to be_falsey end - end describe '#exists' do @@ -183,106 +93,126 @@ def before_hook(delete, missing, noproject, user_cached, project_only) end end - describe '#instances', :noproject => true do + describe '#instances' do it 'finds every user' do + provider.class.expects(:openstack) + .with('user', 'list', '--quiet', '--format', 'csv', ['--long']) + .returns('"ID","Name","Project Id","Domain","Description","Email","Enabled" +"user1_id","user1","project1_id","domain1_id","user1 description","user1@example.com",True +"user2_id","user2","project2_id","domain2_id","user2 description","user2@example.com",True +"user3_id","user3","project3_id","domain3_id","user3 description","user3@example.com",True +') + provider.class.expects(:openstack) + .with('domain', 'list', '--quiet', '--format', 'csv', []) + .returns('"ID","Name","Enabled","Description" +"default","Default",True,"default" +"domain1_id","domain1",True,"domain1" +"domain2_id","domain2",True,"domain2" +"domain3_id","domain3",True,"domain3" +') + provider.class.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'domain1') + .returns('description="" +enabled="True" +id="domain1_id" +name="domain1" +') + provider.class.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'domain2') + .returns('description="" +enabled="True" +id="domain2_id" +name="domain2" +') + provider.class.expects(:openstack) + .with('domain', 'show', '--format', 'shell', 'domain3') + .returns('description="" +enabled="True" +id="domain3_id" +name="domain3" +') instances = provider.class.instances expect(instances.count).to eq(3) - expect(instances[0].name).to eq('foo') - expect(instances[0].domain).to eq('another_domain') - expect(instances[1].name).to eq('foo::foo_domain') - expect(instances[2].name).to eq('foo::bar_domain') + expect(instances[0].name).to eq('user1::domain1') + expect(instances[0].domain).to eq('domain1') + expect(instances[1].name).to eq('user2::domain2') + expect(instances[2].name).to eq('user3::domain3') end end describe '#tenant' do - it 'gets the tenant with default backend', :user_cached => true do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + it 'gets the tenant with default backend' do provider.class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long']) .returns('"ID","Name","Domain ID","Description","Enabled" -"foo_project_id1","foo","foo_domain_id","",True -' - ) - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' +"project2_id","project2","domain2_id","",True +') + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') tenant = provider.tenant - expect(tenant).to eq('foo') + expect(tenant).to eq('project2::domain2') end - it 'gets the tenant with LDAP backend', :user_cached => true do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + it 'gets the tenant with LDAP backend' do + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' provider.class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long']) .returns('"ID","Name","Domain ID","Description","Enabled" -"foo_project_id1","foo","foo_domain_id","",True -"bar_project_id2","bar","bar_domain_id","",True -"foo_project_id2","foo","another_domain_id","",True -' - ) +"project1_id","project1","domain1_id","",True +"project2_id","project2","domain2_id","",True +"project3_id","project3","domain3_id","",True +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') tenant = provider.tenant - expect(tenant).to eq('foo') + expect(tenant).to eq('project2::domain2') end end - describe '#tenant=', :project_only => true do + + describe '#tenant=' do context 'when using default backend' do it 'sets the tenant' do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - provider.instance_variable_get('@property_hash')[:domain] = 'foo_domain' - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.instance_variable_get('@property_hash')[:domain] = 'domain1' provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '2cb05cfed7c24279be884ba4f6520262', '--user', '1cb05cfed7c24279be884ba4f6520262']) - provider.tenant=('bar') + .with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') + provider.tenant=('project2::domain2') end end context 'when using LDAP read-write backend' do it 'sets the tenant when _member_ role exists' do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - provider.instance_variable_get('@property_hash')[:domain] = 'foo_domain' - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.instance_variable_get('@property_hash')[:domain] = 'domain1' provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '2cb05cfed7c24279be884ba4f6520262', '--user', '1cb05cfed7c24279be884ba4f6520262']) - provider.tenant=('bar') + .with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') + provider.tenant=('project2::domain2') end it 'sets the tenant when _member_ role does not exist' do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - provider.instance_variable_get('@property_hash')[:domain] = 'foo_domain' - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.instance_variable_get('@property_hash')[:domain] = 'domain1' provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') .raises(Puppet::ExecutionFailure, 'no such role _member_') @@ -290,27 +220,30 @@ def before_hook(delete, missing, noproject, user_cached, project_only) .with('role', 'create', '--format', 'shell', '_member_') .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '2cb05cfed7c24279be884ba4f6520262', '--user', '1cb05cfed7c24279be884ba4f6520262']) - provider.tenant=('bar') + .with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') + provider.tenant=('project2::domain2') end end - context 'when using LDAP read-only backend', :nohooks => true do + context 'when using LDAP read-only backend' do it 'sets the tenant when _member_ role exists' do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - provider.instance_variable_get('@property_hash')[:domain] = 'foo_domain' - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.instance_variable_get('@property_hash')[:domain] = 'domain1' provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '2cb05cfed7c24279be884ba4f6520262', '--user', '1cb05cfed7c24279be884ba4f6520262']) - provider.tenant=('bar') + .with('role', 'add', ['_member_', '--project', 'project2_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project2', '--domain', 'domain2']) + .returns('name="project2" +id="project2_id" +') + provider.tenant=('project2::domain2') end end end @@ -325,7 +258,7 @@ def before_hook(delete, missing, noproject, user_cached, project_only) :password => 'foo', :tenant => 'foo', :email => 'foo@example.com', - :domain => 'foo_domain', + :domain => 'domain1', } end @@ -337,41 +270,58 @@ def before_hook(delete, missing, noproject, user_cached, project_only) provider_class.new(resource) end - it 'checks the password', :noproject_user_cached => true do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' + it 'checks the password' do + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' mock_creds = Puppet::Provider::Openstack::CredentialsV3.new mock_creds.auth_url='http://127.0.0.1:5000' mock_creds.password='foo' mock_creds.username='foo' - mock_creds.user_id='1cb05cfed7c24279be884ba4f6520262' + mock_creds.user_id='project1_id' mock_creds.project_id='project-id-1' Puppet::Provider::Openstack::CredentialsV3.expects(:new).returns(mock_creds) + + provider.class.expects(:openstack) + .with('domain', 'list', '--quiet', '--format', 'csv', []) + .returns('"ID","Name","Enabled","Description" +"default","Default",True,"default" +"domain1_id","domain1",True,"domain1" +"domain2_id","domain2",True,"domain2" +') + provider.class.expects(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long']) + .returns('"ID","Name","Domain ID","Description","Enabled" +"project2_id","project2","domain2_id","",True +') Puppet::Provider::Openstack.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'project1_id', '--long']) .returns('"ID","Name","Domain ID","Description","Enabled" -"project-id-1","foo","foo_domain_id","foo",True -' - ) +"project-id-1","foo","domain1_id","foo",True +') Puppet::Provider::Openstack.expects(:openstack) .with('token', 'issue', ['--format', 'value']) .returns('2015-05-14T04:06:05Z e664a386befa4a30878dcef20e79f167 8dce2ae9ecd34c199d2877bf319a3d06 ac43ec53d5a74a0b9f51523ae41a29f0 -' - ) +') password = provider.password expect(password).to eq('foo') end - it 'fails the password check', :noproject_user_cached => true do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' + it 'fails the password check' do + provider.instance_variable_get('@property_hash')[:id] = 'user1_id' + provider.class.expects(:openstack) + .with('domain', 'list', '--quiet', '--format', 'csv', []) + .returns('"ID","Name","Enabled","Description" +"default","Default",True,"default" +"domain1_id","domain1",True,"domain1" +"domain2_id","domain2",True,"domain2" +') Puppet::Provider::Openstack.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long']) .returns('"ID","Name","Domain ID","Description","Enabled" -"project-id-1","foo","foo_domain_id","foo",True -' - ) +"project-id-1","foo","domain1_id","foo",True +') Puppet::Provider::Openstack.expects(:openstack) .with('token', 'issue', ['--format', 'value']) .raises(Puppet::ExecutionFailure, 'HTTP 401 invalid authentication') @@ -379,48 +329,46 @@ def before_hook(delete, missing, noproject, user_cached, project_only) expect(password).to eq(nil) end - it 'checks the password with domain scoped token', :nohooks => true do - provider.instance_variable_get('@property_hash')[:id] = '1cb05cfed7c24279be884ba4f6520262' - provider.instance_variable_get('@property_hash')[:domain] = 'foo_domain' + it 'checks the password with domain scoped token' do + provider.instance_variable_get('@property_hash')[:id] = 'project1_id' + provider.instance_variable_get('@property_hash')[:domain] = 'domain1' mock_creds = Puppet::Provider::Openstack::CredentialsV3.new mock_creds.auth_url='http://127.0.0.1:5000' mock_creds.password='foo' mock_creds.username='foo' - mock_creds.user_id='1cb05cfed7c24279be884ba4f6520262' - mock_creds.domain_name='foo_domain' + mock_creds.user_id='project1_id' + mock_creds.domain_name='domain1' Puppet::Provider::Openstack::CredentialsV3.expects(:new).returns(mock_creds) Puppet::Provider::Openstack.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'project1_id', '--long']) .returns('"ID","Name","Domain ID","Description","Enabled" -' - ) +') Puppet::Provider::Openstack.expects(:openstack) .with('token', 'issue', ['--format', 'value']) .returns('2015-05-14T04:06:05Z e664a386befa4a30878dcef20e79f167 8dce2ae9ecd34c199d2877bf319a3d06 ac43ec53d5a74a0b9f51523ae41a29f0 -' - ) +') password = provider.password expect(password).to eq('foo') end end - describe 'when updating a user with unmanaged password', :nohooks => true do + describe 'when updating a user with unmanaged password' do describe 'when updating a user with unmanaged password' do let(:user_attrs) do { - :name => 'foo', + :name => 'user1', :ensure => 'present', :enabled => 'True', - :password => 'foo', + :password => 'secret', :replace_password => 'False', - :tenant => 'foo', - :email => 'foo@example.com', - :domain => 'foo_domain', + :tenant => 'project2', + :email => 'user1@example.com', + :domain => 'domain1', } end @@ -433,240 +381,178 @@ def before_hook(delete, missing, noproject, user_cached, project_only) end it 'should not try to check password' do - expect(provider.password).to eq('foo') + expect(provider.password).to eq('secret') end end end - describe 'v3 domains with no domain in resource', :user_cached => true do + describe 'v3 domains with no domain in resource' do let(:user_attrs) do { - :name => 'foo', - :ensure => 'present', - :enabled => 'True', - :password => 'foo', - :tenant => 'foo', - :email => 'foo@example.com', + :name => 'user1', + :ensure => 'present', + :enabled => 'True', + :password => 'secret', + :tenant => 'project1::domain2', + :email => 'user1@example.com', } end it 'adds default domain to commands' do mock = { - 'identity' => {'default_domain_id' => 'foo_domain_id'} + 'identity' => {'default_domain_id' => 'domain1_id'} } Puppet::Util::IniConfig::File.expects(:new).returns(mock) File.expects(:exists?).with('/etc/keystone/keystone.conf').returns(true) mock.expects(:read).with('/etc/keystone/keystone.conf') provider.class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', ['--user', '1cb05cfed7c24279be884ba4f6520262', '--long']) + .with('domain', 'list', '--quiet', '--format', 'csv', []) + .returns('"ID","Name","Enabled","Description" +"domain1_id","domain1",True,"domain1" +"domain2_id","domain2",True,"domain2" +') + provider.class.expects(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', ['--user', 'user1_id', '--long']) .returns('"ID","Name" -' - ) - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) +') provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') .returns(' name="_member_" -' - ) +') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '1cb05cfed7c24279be884ba4f6520262', '--user', '1cb05cfed7c24279be884ba4f6520262']) + .with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'foo_domain']) - .returns('email="foo@example.com" + .with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1']) + .returns('email="user1@example.com" enabled="True" -id="1cb05cfed7c24279be884ba4f6520262" -name="foo" -username="foo" -' - ) +id="user1_id" +name="user1" +username="user1" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2']) + .returns('name="project1" +id="project1_id" +') provider.create expect(provider.exists?).to be_truthy - expect(provider.id).to eq("1cb05cfed7c24279be884ba4f6520262") + expect(provider.id).to eq("user1_id") end end - describe 'v3 domains with domain in resource', :project_only => true do + describe 'v3 domains with domain in resource' do let(:user_attrs) do { - :name => 'foo', - :ensure => 'present', - :enabled => 'True', - :password => 'foo', - :tenant => 'foo', - :email => 'foo@example.com', - :domain => 'bar_domain', + :name => 'user1', + :ensure => 'present', + :enabled => 'True', + :password => 'secret', + :tenant => 'project1::domain2', + :email => 'user1@example.com', + :domain => 'domain1', } end it 'uses given domain in commands' do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') - .returns(' -name="_member_" -' - ) + .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '1cb05cfed7c24279be884ba4f6520262', '--user', '2cb05cfed7c24279be884ba4f6520262']) + .with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'bar_domain']) - .returns('email="foo@example.com" + .with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1']) + .returns('email="user1@example.com" enabled="True" -id="2cb05cfed7c24279be884ba4f6520262" -name="foo" -username="foo" -' - ) +id="user1_id" +name="user1" +username="user1" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2']) + .returns('name="projec1" +id="project1_id" +') provider.create expect(provider.exists?).to be_truthy - expect(provider.id).to eq("2cb05cfed7c24279be884ba4f6520262") + expect(provider.id).to eq("user1_id") end end - describe 'v3 domains with domain in name/title', :project_only => true do + describe 'v3 domains with domain in name/title' do let(:user_attrs) do { - :name => 'foo::bar_domain', + :name => 'user1::domain1', :ensure => 'present', :enabled => 'True', - :password => 'foo', - :tenant => 'foo', - :email => 'foo@example.com', + :password => 'secret', + :tenant => 'project1::domain2', + :email => 'user1@example.com', } end it 'uses given domain in commands' do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') - .returns(' -name="_member_" -' - ) + .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '1cb05cfed7c24279be884ba4f6520262', '--user', '2cb05cfed7c24279be884ba4f6520262']) + .with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'bar_domain']) - .returns('email="foo@example.com" + .with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1']) + .returns('email="user1@example.com" enabled="True" -id="2cb05cfed7c24279be884ba4f6520262" -name="foo" -username="foo" -' - ) - provider.create - expect(provider.exists?).to be_truthy - expect(provider.id).to eq("2cb05cfed7c24279be884ba4f6520262") - expect(provider.name).to eq('foo::bar_domain') - end - end - - describe 'v3 domains with domain in name/title and in resource', :project_only => true do - let(:user_attrs) do - { - :name => 'foo::bar_domain', - :ensure => 'present', - :enabled => 'True', - :password => 'foo', - :tenant => 'foo', - :email => 'foo@example.com', - :domain => 'foo_domain', - } - end - - it 'uses the resource domain in commands' do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","bar","bar_domain_id","bar",True -' - ) - provider.class.expects(:openstack) - .with('role', 'show', '--format', 'shell', '_member_') - .returns(' -name="_member_" -' - ) - provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '1cb05cfed7c24279be884ba4f6520262', '--user', '2cb05cfed7c24279be884ba4f6520262']) +id="user1_id" +name="user1" +username="user1" +') provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'foo_domain']) - .returns('email="foo@example.com" -enabled="True" -id="2cb05cfed7c24279be884ba4f6520262" -name="foo" -username="foo" -' - ) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2']) + .returns('name="project1" +id="project1_id" +') provider.create expect(provider.exists?).to be_truthy - expect(provider.id).to eq("2cb05cfed7c24279be884ba4f6520262") - expect(provider.name).to eq('foo::bar_domain') + expect(provider.id).to eq("user1_id") + expect(provider.name).to eq('user1::domain1') end end - describe 'v3 domains with domain in name/title and in resource and in tenant', :project_only => true do + describe 'v3 domains with domain in name/title and in resource' do let(:user_attrs) do { - :name => 'foo::bar_domain', + :name => 'user1::domain1', :ensure => 'present', :enabled => 'True', - :password => 'foo', - :tenant => 'foo::foo_domain', - :email => 'foo@example.com', - :domain => 'foo_domain', + :password => 'secret', + :tenant => 'project1::domain2', + :email => 'user1@example.com', + :domain => 'domain1', } end it 'uses the resource domain in commands' do - project_class.expects(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', '--long') - .returns('"ID","Name","Domain ID","Description","Enabled" -"1cb05cfed7c24279be884ba4f6520262","foo","foo_domain_id","foo",True -"2cb05cfed7c24279be884ba4f6520262","foo","bar_domain_id","foo",True -' - ) provider.class.expects(:openstack) .with('role', 'show', '--format', 'shell', '_member_') - .returns(' -name="_member_" -' - ) + .returns('name="_member_"') provider.class.expects(:openstack) - .with('role', 'add', ['_member_', '--project', '1cb05cfed7c24279be884ba4f6520262', '--user', '2cb05cfed7c24279be884ba4f6520262']) + .with('role', 'add', ['_member_', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--email', 'foo@example.com', '--domain', 'foo_domain']) - .returns('email="foo@example.com" + .with('user', 'create', '--format', 'shell', ['user1', '--enable', '--password', 'secret', '--email', 'user1@example.com', '--domain', 'domain1']) + .returns('email="user1@example.com" enabled="True" -id="2cb05cfed7c24279be884ba4f6520262" -name="foo" -username="foo" -' - ) +id="user1_id" +name="user1" +username="user1" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain2']) + .returns('name="project1" +id="project1_id" +') provider.create expect(provider.exists?).to be_truthy - expect(provider.id).to eq("2cb05cfed7c24279be884ba4f6520262") - expect(provider.name).to eq('foo::bar_domain') + expect(provider.id).to eq("user1_id") + expect(provider.name).to eq('user1::domain1') end end end diff --git a/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb b/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb index c6b521a0b..b44bf35e6 100644 --- a/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb +++ b/keystone/spec/unit/provider/keystone_user_role/openstack_spec.rb @@ -5,138 +5,9 @@ setup_provider_tests provider_class = Puppet::Type.type(:keystone_user_role).provider(:openstack) -def user_class - Puppet::Type.type(:keystone_user).provider(:openstack) -end -def project_class - Puppet::Type.type(:keystone_tenant).provider(:openstack) -end describe provider_class do - after :each do - provider_class.reset - end - - # assumes Enabled is the last column - no quotes - def list_to_csv(thelist) - if thelist.is_a?(String) - return '' - end - str="" - thelist.each do |rec| - if rec.is_a?(String) - return '' - end - rec.each do |xx| - if xx.equal?(rec.last) - # True/False have no quotes - if xx == 'True' or xx == 'False' - str = str + xx + "\n" - else - str = str + '"' + xx + '"' + "\n" - end - else - str = str + '"' + xx + '",' - end - end - end - str - end - - def before_need_instances - provider.class.expects(:openstack).once - .with('domain', 'list', '--quiet', '--format', 'csv') - .returns('"ID","Name","Enabled","Description" -"foo_domain_id","foo_domain",True,"foo domain" -"bar_domain_id","bar_domain",True,"bar domain" -"another_domain_id","another_domain",True,"another domain" -"disabled_domain_id","disabled_domain",False,"disabled domain" -') - project_list = [['project-id-1','foo','foo_domain_id','foo project in foo domain','True'], - ['project-id-2','foo','bar_domain_id','foo project in bar domain','True'], - ['project-id-3','bar','foo_domain_id','bar project in foo domain','True'], - ['project-id-4','etc','another_domain_id','another project','True']] - - user_list_for_project = { - 'project-id-1' => [['user-id-1','foo@example.com','foo','foo_domain','foo user','foo@foo_domain','True'], - ['user-id-2','bar@example.com','foo','foo_domain','bar user','bar@foo_domain','True']], - 'project-id-2' => [['user-id-3','foo@bar.com','foo','bar_domain','foo user','foo@bar_domain','True'], - ['user-id-4','bar@bar.com','foo','bar_domain','bar user','bar@bar_domain','True']] - } - user_list_for_project.default = '' - - user_list_for_domain = { - 'foo_domain_id' => [['user-id-1','foo@example.com','foo','foo_domain','foo user','foo@foo_domain','True'], - ['user-id-2','bar@example.com','foo','foo_domain','bar user','bar@foo_domain','True']], - 'bar_domain_id' => [['user-id-3','foo@bar.com','foo','bar_domain','foo user','foo@bar_domain','True'], - ['user-id-4','bar@bar.com','foo','bar_domain','bar user','bar@bar_domain','True']] - } - user_list_for_domain.default = '' - - role_list_for_project_user = { - 'project-id-1' => { - 'user-id-1' => [['role-id-1','foo','foo','foo'], - ['role-id-2','bar','foo','foo']] - }, - 'project-id-2' => { - 'user-id-3' => [['role-id-1','foo','foo','foo'], - ['role-id-2','bar','foo','foo']] - } - } - role_list_for_project_user.default = '' - - role_list_for_domain_user = { - 'foo_domain_id' => { - 'user-id-2' => [['role-id-1','foo','foo_domain','foo'], - ['role-id-2','bar','foo_domain','foo']] - }, - 'bar_domain_id' => { - 'user-id-4' => [['role-id-1','foo','bar_domain','foo'], - ['role-id-2','bar','bar_domain','foo']] - } - } - role_list_for_project_user.default = '' - - provider.class.expects(:openstack).once - .with('project', 'list', '--quiet', '--format', 'csv', ['--long']) - .returns('"ID","Name","Domain ID","Description","Enabled"' + "\n" + list_to_csv(project_list)) - project_list.each do |rec| - csvlist = list_to_csv(user_list_for_project[rec[0]]) - provider.class.expects(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', ['--long', '--project', rec[0]]) - .returns('"ID","Name","Project","Domain","Description","Email","Enabled"' + "\n" + csvlist) - next if csvlist == '' - user_list_for_project[rec[0]].each do |urec| - csvlist = '' - if role_list_for_project_user.has_key?(rec[0]) and - role_list_for_project_user[rec[0]].has_key?(urec[0]) - csvlist = list_to_csv(role_list_for_project_user[rec[0]][urec[0]]) - end - provider.class.expects(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', ['--project', rec[0], '--user', urec[0]]) - .returns('"ID","Name","Project","User"' + "\n" + csvlist) - end - end - ['foo_domain_id', 'bar_domain_id'].each do |domid| - csvlist = list_to_csv(user_list_for_domain[domid]) - provider.class.expects(:openstack) - .with('user', 'list', '--quiet', '--format', 'csv', ['--long', '--domain', domid]) - .returns('"ID","Name","Project","Domain","Description","Email","Enabled"' + "\n" + csvlist) - next if csvlist == '' - user_list_for_domain[domid].each do |urec| - csvlist = '' - if role_list_for_domain_user.has_key?(domid) and - role_list_for_domain_user[domid].has_key?(urec[0]) - csvlist = list_to_csv(role_list_for_domain_user[domid][urec[0]]) - end - provider.class.expects(:openstack) - .with('role', 'list', '--quiet', '--format', 'csv', ['--domain', domid, '--user', urec[0]]) - .returns('"ID","Name","Domain","User"' + "\n" + csvlist) - end - end - end - let(:set_env) do ENV['OS_USERNAME'] = 'test' ENV['OS_PASSWORD'] = 'abc123' @@ -144,62 +15,16 @@ def before_need_instances ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000' end - def before_common(destroy, nolist=false, instances=false) - set_env - rolelistprojectuser = [['role-id-1','foo','foo','foo'], - ['role-id-2','bar','foo','foo']] - csvlist = list_to_csv(rolelistprojectuser) - rolelistreturns = ['"ID","Name","Project","User"' + "\n" + csvlist] - nn = 1 - if destroy - rolelistreturns = [''] - nn = 1 - end - unless nolist - provider.class.expects(:openstack).times(nn) - .with('role', 'list', '--quiet', '--format', 'csv', ['--project', 'project-id-1', '--user', 'user-id-1']) - .returns(*rolelistreturns) - end - - userhash = {:id => 'user-id-1', :name => 'foo@example.com'} - usermock = user_class.new(userhash) - unless instances - usermock.expects(:exists?).with(any_parameters).returns(true) - user_class.expects(:new).twice.with(any_parameters).returns(usermock) - end - user_class.expects(:instances).with(any_parameters).returns([usermock]) - - projecthash = {:id => 'project-id-1', :name => 'foo'} - projectmock = project_class.new(projecthash) - unless instances - projectmock.expects(:exists?).with(any_parameters).returns(true) - project_class.expects(:new).with(any_parameters).returns(projectmock) - end - project_class.expects(:instances).with(any_parameters).returns([projectmock]) - end - - before :each, :default => true do - before_common(false) - end + before(:each) { set_env } - before :each, :destroy => true do - before_common(true) - end + after(:each) { provider_class.reset } - before :each, :nolist => true do - before_common(true, true) - end - - before :each, :instances => true do - before_common(true, true, true) - end - - describe 'when updating a user\'s role' do + describe 'when managing a user\'s role' do let(:user_role_attrs) do { - :name => 'foo@foo', + :name => 'user1::domain1@project1::domain1', :ensure => 'present', - :roles => ['foo', 'bar'], + :roles => ['role1', 'role2'], } end @@ -211,62 +36,116 @@ def before_common(destroy, nolist=false, instances=false) provider_class.new(resource) end - describe '#create', :default => true do + describe '#create' do it 'adds all the roles to the user' do + + provider.class.expects(:openstack) + .with('role', 'list', '--quiet', '--format', 'csv', ['--project', 'project1_id', '--user', 'user1_id' ]) + .returns('"ID","Name","Project","User" +"role1_id","role1","project1","user1" +"role2_id","role2","project1","user1" +') + provider.class.expects(:openstack) + .with('role', 'add', ['role1', '--project', 'project1_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('role', 'add', ['role2', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('role', 'add', ['foo', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain1']) + .returns('name="project1" +id="project1_id" +') provider.class.expects(:openstack) - .with('role', 'add', ['bar', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('user', 'show', '--format', 'shell', ['user1', '--domain', 'domain1']) + .returns('name="user1" +id="user1_id" +') provider.create expect(provider.exists?).to be_truthy end end - describe '#destroy', :destroy => true do + describe '#destroy' do it 'removes all the roles from a user' do - provider.instance_variable_get('@property_hash')[:roles] = ['foo', 'bar'] + provider.instance_variable_get('@property_hash')[:roles] = ['role1', 'role2'] provider.class.expects(:openstack) - .with('role', 'remove', ['foo', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('role', 'remove', ['role1', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('role', 'remove', ['bar', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('role', 'remove', ['role2', '--project', 'project1_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain1']) + .returns('name="project1" +id="project1_id" +') + provider.class.expects(:openstack) + .with('user', 'show', '--format', 'shell', ['user1', '--domain', 'domain1']) + .returns('name="user1" +id="user1_id" +') + provider.class.expects(:openstack) + .with('role', 'list', '--quiet', '--format', 'csv', ['--project', 'project1_id', '--user', 'user1_id']) + .returns('"ID","Name","Project","User" +') provider.destroy expect(provider.exists?).to be_falsey end - end - describe '#exists', :default => true do + describe '#exists' do subject(:response) do + provider.class.expects(:openstack) + .with('role', 'list', '--quiet', '--format', 'csv', ['--project', 'project1_id', '--user', 'user1_id' ]) + .returns('"ID","Name","Project","User" +"role1_id","role1","project1","user1" +"role2_id","role2","project1","user1" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['project1', '--domain', 'domain1']) + .returns('name="project1" +id="project1_id" +') + provider.class.expects(:openstack) + .with('user', 'show', '--format', 'shell', ['user1', '--domain', 'domain1']) + .returns('name="user1" +id="user1_id" +') response = provider.exists? end it { is_expected.to be_truthy } - end - describe '#instances', :instances => true do + describe '#instances' do it 'finds every user role' do + project_class = Puppet::Type.type(:keystone_tenant).provider(:openstack) + user_class = Puppet::Type.type(:keystone_user).provider(:openstack) + + usermock = user_class.new({:id => 'user1_id', :name => 'user1'}) + user_class.expects(:instances).with(any_parameters).returns([usermock]) + + projectmock = project_class.new({:id => 'project1_id', :name => 'project1'}) + project_class.expects(:instances).with(any_parameters).returns([projectmock]) + provider.class.expects(:openstack) .with('role', 'list', '--quiet', '--format', 'csv', []) .returns('"ID","Name" -"foo-role-id","foo" -"bar-role-id","bar" +"role1-id","role1" +"role2-id","role2" ') provider.class.expects(:openstack) .with('role assignment', 'list', '--quiet', '--format', 'csv', []) .returns(' "Role","User","Group","Project","Domain" -"foo-role-id","user-id-1","","project-id-1","" -"bar-role-id","user-id-1","","project-id-1","" +"role1-id","user1_id","","project1_id","" +"role2-id","user1_id","","project1_id","" ') instances = provider.class.instances expect(instances.count).to eq(1) - expect(instances[0].name).to eq('foo@example.com@foo') - expect(instances[0].roles).to eq(['foo', 'bar']) + expect(instances[0].name).to eq('user1@project1') + expect(instances[0].roles).to eq(['role1', 'role2']) end end - describe '#roles=', :nolist => true do + describe '#roles=' do let(:user_role_attrs) do { :name => 'foo@foo', @@ -275,16 +154,31 @@ def before_common(destroy, nolist=false, instances=false) } end - it 'applies the new roles' do + it 'applies new roles' do provider.instance_variable_get('@property_hash')[:roles] = ['foo', 'bar'] provider.class.expects(:openstack) - .with('role', 'remove', ['foo', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('role', 'remove', ['foo', '--project', 'project1_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('role', 'remove', ['bar', '--project', 'project1_id', '--user', 'user1_id']) + provider.class.expects(:openstack) + .with('role', 'add', ['one', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('role', 'remove', ['bar', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('role', 'add', ['two', '--project', 'project1_id', '--user', 'user1_id']) provider.class.expects(:openstack) - .with('role', 'add', ['one', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('domain', 'list', '--quiet', '--format', 'csv', []) + .returns('"ID","Name","Enabled","Description" +"default","Default",True,"Default Domain" +') + provider.class.expects(:openstack) + .with('project', 'show', '--format', 'shell', ['foo', '--domain', 'Default']) + .returns('name="foo" +id="project1_id" +') provider.class.expects(:openstack) - .with('role', 'add', ['two', '--project', 'project-id-1', '--user', 'user-id-1']) + .with('user', 'show', '--format', 'shell', ['foo', '--domain', 'Default']) + .returns('name="foo" +id="user1_id" +') provider.roles=(['one', 'two']) end end diff --git a/manila/manifests/init.pp b/manila/manifests/init.pp index 95a1ad627..d489ffaac 100644 --- a/manila/manifests/init.pp +++ b/manila/manifests/init.pp @@ -145,6 +145,10 @@ # (Optional) ENable one or more SASL mechanisms. # Defaults to false. # +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to undef +# # [*use_syslog*] # Use syslog for logging. # (Optional) Defaults to false. @@ -281,11 +285,12 @@ $cert_file = false, $key_file = false, $api_paste_config = '/etc/manila/api-paste.ini', - $use_syslog = false, - $log_facility = 'LOG_USER', - $log_dir = '/var/log/manila', - $verbose = false, - $debug = false, + $use_stderr = undef, + $use_syslog = undef, + $log_facility = undef, + $log_dir = undef, + $verbose = undef, + $debug = undef, $storage_availability_zone = 'nova', $rootwrap_config = '/etc/manila/rootwrap.conf', $state_path = '/var/lib/manila', @@ -303,6 +308,7 @@ $amqp_ssl_key_password = undef, ) { + include ::manila::logging include ::manila::params if $use_ssl { @@ -494,8 +500,6 @@ manila_config { 'DEFAULT/sql_connection': value => $sql_connection, secret => true; 'DEFAULT/sql_idle_timeout': value => $sql_idle_timeout; - 'DEFAULT/verbose': value => $verbose; - 'DEFAULT/debug': value => $debug; 'DEFAULT/api_paste_config': value => $api_paste_config; 'DEFAULT/rpc_backend': value => $rpc_backend; 'DEFAULT/storage_availability_zone': value => $storage_availability_zone; @@ -516,16 +520,6 @@ fail("Invalid db connection ${sql_connection}") } - if $log_dir { - manila_config { - 'DEFAULT/log_dir': value => $log_dir; - } - } else { - manila_config { - 'DEFAULT/log_dir': ensure => absent; - } - } - # SSL Options if $use_ssl { manila_config { @@ -549,15 +543,4 @@ } } - if $use_syslog { - manila_config { - 'DEFAULT/use_syslog': value => true; - 'DEFAULT/syslog_log_facility': value => $log_facility; - } - } else { - manila_config { - 'DEFAULT/use_syslog': value => false; - } - } - } diff --git a/manila/manifests/logging.pp b/manila/manifests/logging.pp new file mode 100644 index 000000000..6b3136014 --- /dev/null +++ b/manila/manifests/logging.pp @@ -0,0 +1,257 @@ +# Class manila::logging +# +# manila logging configuration +# +# == parameters +# +# [*verbose*] +# (Optional) Should the daemons log verbose messages +# Defaults to 'false' +# +# [*debug*] +# (Optional) Should the daemons log debug messages +# Defaults to 'false' +# +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to 'false' +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to 'true' +# +# [*log_facility*] +# (Optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER' +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false, it will not log to any directory. +# Defaults to '/var/log/manila' +# +# [*logging_context_format_string*] +# (optional) Format string to use for log messages with context. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [%(request_id)s %(user_identity)s] %(instance)s%(message)s' +# +# [*logging_default_format_string*] +# (optional) Format string to use for log messages without context. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [-] %(instance)s%(message)s' +# +# [*logging_debug_format_suffix*] +# (optional) Formatted data to append to log format when level is DEBUG. +# Defaults to undef. +# Example: '%(funcName)s %(pathname)s:%(lineno)d' +# +# [*logging_exception_prefix*] +# (optional) Prefix each line of exception output with this format. +# Defaults to undef. +# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s' +# +# [*log_config_append*] +# The name of an additional logging configuration file. +# Defaults to undef. +# See https://docs.python.org/2/howto/logging.html +# +# [*default_log_levels*] +# (optional) Hash of logger (keys) and level (values) pairs. +# Defaults to undef. +# Example: +# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', +# 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', +# 'iso8601' => 'WARN', +# 'requests.packages.urllib3.connectionpool' => 'WARN' } +# +# [*publish_errors*] +# (optional) Publish error events (boolean value). +# Defaults to undef (false if unconfigured). +# +# [*fatal_deprecations*] +# (optional) Make deprecations fatal (boolean value) +# Defaults to undef (false if unconfigured). +# +# [*instance_format*] +# (optional) If an instance is passed with the log message, format it +# like this (string value). +# Defaults to undef. +# Example: '[instance: %(uuid)s] ' +# +# [*instance_uuid_format*] +# (optional) If an instance UUID is passed with the log message, format +# it like this (string value). +# Defaults to undef. +# Example: instance_uuid_format='[instance: %(uuid)s] ' + +# [*log_date_format*] +# (optional) Format string for %%(asctime)s in log records. +# Defaults to undef. +# Example: 'Y-%m-%d %H:%M:%S' + +class manila::logging( + $use_syslog = false, + $use_stderr = true, + $log_facility = 'LOG_USER', + $log_dir = '/var/log/manila', + $verbose = false, + $debug = false, + $logging_context_format_string = undef, + $logging_default_format_string = undef, + $logging_debug_format_suffix = undef, + $logging_exception_prefix = undef, + $log_config_append = undef, + $default_log_levels = undef, + $publish_errors = undef, + $fatal_deprecations = undef, + $instance_format = undef, + $instance_uuid_format = undef, + $log_date_format = undef, +) { + + # NOTE(spredzy): In order to keep backward compatibility we rely on the pick function + # to use manila:: first then manila::logging::. + $use_syslog_real = pick($::manila::use_syslog,$use_syslog) + $use_stderr_real = pick($::manila::use_stderr,$use_stderr) + $log_facility_real = pick($::manila::log_facility,$log_facility) + $log_dir_real = pick($::manila::log_dir,$log_dir) + $verbose_real = pick($::manila::verbose,$verbose) + $debug_real = pick($::manila::debug,$debug) + + manila_config { + 'DEFAULT/debug' : value => $debug_real; + 'DEFAULT/verbose' : value => $verbose_real; + 'DEFAULT/use_stderr' : value => $use_stderr_real; + 'DEFAULT/use_syslog' : value => $use_syslog_real; + 'DEFAULT/log_dir' : value => $log_dir_real; + 'DEFAULT/syslog_log_facility': value => $log_facility_real; + } + + if $logging_context_format_string { + manila_config { + 'DEFAULT/logging_context_format_string' : + value => $logging_context_format_string; + } + } + else { + manila_config { + 'DEFAULT/logging_context_format_string' : ensure => absent; + } + } + + if $logging_default_format_string { + manila_config { + 'DEFAULT/logging_default_format_string' : + value => $logging_default_format_string; + } + } + else { + manila_config { + 'DEFAULT/logging_default_format_string' : ensure => absent; + } + } + + if $logging_debug_format_suffix { + manila_config { + 'DEFAULT/logging_debug_format_suffix' : + value => $logging_debug_format_suffix; + } + } + else { + manila_config { + 'DEFAULT/logging_debug_format_suffix' : ensure => absent; + } + } + + if $logging_exception_prefix { + manila_config { + 'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix; + } + } + else { + manila_config { + 'DEFAULT/logging_exception_prefix' : ensure => absent; + } + } + + if $log_config_append { + manila_config { + 'DEFAULT/log_config_append' : value => $log_config_append; + } + } + else { + manila_config { + 'DEFAULT/log_config_append' : ensure => absent; + } + } + + if $default_log_levels { + manila_config { + 'DEFAULT/default_log_levels' : + value => join(sort(join_keys_to_values($default_log_levels, '=')), ','); + } + } + else { + manila_config { + 'DEFAULT/default_log_levels' : ensure => absent; + } + } + + if $publish_errors { + manila_config { + 'DEFAULT/publish_errors' : value => $publish_errors; + } + } + else { + manila_config { + 'DEFAULT/publish_errors' : ensure => absent; + } + } + + if $fatal_deprecations { + manila_config { + 'DEFAULT/fatal_deprecations' : value => $fatal_deprecations; + } + } + else { + manila_config { + 'DEFAULT/fatal_deprecations' : ensure => absent; + } + } + + if $instance_format { + manila_config { + 'DEFAULT/instance_format' : value => $instance_format; + } + } + else { + manila_config { + 'DEFAULT/instance_format' : ensure => absent; + } + } + + if $instance_uuid_format { + manila_config { + 'DEFAULT/instance_uuid_format' : value => $instance_uuid_format; + } + } + else { + manila_config { + 'DEFAULT/instance_uuid_format' : ensure => absent; + } + } + + if $log_date_format { + manila_config { + 'DEFAULT/log_date_format' : value => $log_date_format; + } + } + else { + manila_config { + 'DEFAULT/log_date_format' : ensure => absent; + } + } + + +} diff --git a/manila/spec/classes/manila_logging_spec.rb b/manila/spec/classes/manila_logging_spec.rb new file mode 100644 index 000000000..0abc76644 --- /dev/null +++ b/manila/spec/classes/manila_logging_spec.rb @@ -0,0 +1,143 @@ +require 'spec_helper' + +describe 'manila::logging' do + + let :params do + { + } + end + + let :log_params do + { + :logging_context_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s', + :logging_default_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s', + :logging_debug_format_suffix => '%(funcName)s %(pathname)s:%(lineno)d', + :logging_exception_prefix => '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s', + :log_config_append => '/etc/manila/logging.conf', + :publish_errors => true, + :default_log_levels => { + 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', + 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO', + 'iso8601' => 'WARN', + 'requests.packages.urllib3.connectionpool' => 'WARN' }, + :fatal_deprecations => true, + :instance_format => '[instance: %(uuid)s] ', + :instance_uuid_format => '[instance: %(uuid)s] ', + :log_date_format => '%Y-%m-%d %H:%M:%S', + :use_syslog => true, + :use_stderr => false, + :log_facility => 'LOG_FOO', + :log_dir => '/var/log', + :verbose => true, + :debug => true, + } + end + + shared_examples_for 'manila-logging' do + + context 'with basic logging options and default settings' do + it_configures 'basic default logging settings' + end + + context 'with basic logging options and non-default settings' do + before { params.merge!( log_params ) } + it_configures 'basic non-default logging settings' + end + + context 'with extended logging options' do + before { params.merge!( log_params ) } + it_configures 'logging params set' + end + + context 'without extended logging options' do + it_configures 'logging params unset' + end + + end + + shared_examples 'basic default logging settings' do + it 'configures manila logging settins with default values' do + is_expected.to contain_manila_config('DEFAULT/use_syslog').with(:value => 'false') + is_expected.to contain_manila_config('DEFAULT/use_stderr').with(:value => 'true') + is_expected.to contain_manila_config('DEFAULT/log_dir').with(:value => '/var/log/manila') + is_expected.to contain_manila_config('DEFAULT/verbose').with(:value => 'false') + is_expected.to contain_manila_config('DEFAULT/debug').with(:value => 'false') + end + end + + shared_examples 'basic non-default logging settings' do + it 'configures manila logging settins with non-default values' do + is_expected.to contain_manila_config('DEFAULT/use_syslog').with(:value => 'true') + is_expected.to contain_manila_config('DEFAULT/use_stderr').with(:value => 'false') + is_expected.to contain_manila_config('DEFAULT/syslog_log_facility').with(:value => 'LOG_FOO') + is_expected.to contain_manila_config('DEFAULT/log_dir').with(:value => '/var/log') + is_expected.to contain_manila_config('DEFAULT/verbose').with(:value => 'true') + is_expected.to contain_manila_config('DEFAULT/debug').with(:value => 'true') + end + end + + shared_examples_for 'logging params set' do + it 'enables logging params' do + is_expected.to contain_manila_config('DEFAULT/logging_context_format_string').with_value( + '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s') + + is_expected.to contain_manila_config('DEFAULT/logging_default_format_string').with_value( + '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s') + + is_expected.to contain_manila_config('DEFAULT/logging_debug_format_suffix').with_value( + '%(funcName)s %(pathname)s:%(lineno)d') + + is_expected.to contain_manila_config('DEFAULT/logging_exception_prefix').with_value( + '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s') + + is_expected.to contain_manila_config('DEFAULT/log_config_append').with_value( + '/etc/manila/logging.conf') + is_expected.to contain_manila_config('DEFAULT/publish_errors').with_value( + true) + + is_expected.to contain_manila_config('DEFAULT/default_log_levels').with_value( + 'amqp=WARN,amqplib=WARN,boto=WARN,iso8601=WARN,qpid=WARN,requests.packages.urllib3.connectionpool=WARN,sqlalchemy=WARN,suds=INFO') + + is_expected.to contain_manila_config('DEFAULT/fatal_deprecations').with_value( + true) + + is_expected.to contain_manila_config('DEFAULT/instance_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_manila_config('DEFAULT/instance_uuid_format').with_value( + '[instance: %(uuid)s] ') + + is_expected.to contain_manila_config('DEFAULT/log_date_format').with_value( + '%Y-%m-%d %H:%M:%S') + end + end + + + shared_examples_for 'logging params unset' do + [ :logging_context_format_string, :logging_default_format_string, + :logging_debug_format_suffix, :logging_exception_prefix, + :log_config_append, :publish_errors, + :default_log_levels, :fatal_deprecations, + :instance_format, :instance_uuid_format, + :log_date_format, ].each { |param| + it { is_expected.to contain_manila_config("DEFAULT/#{param}").with_ensure('absent') } + } + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'manila-logging' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'manila-logging' + end + +end diff --git a/manila/spec/classes/manila_spec.rb b/manila/spec/classes/manila_spec.rb index 5069c26fc..c4fcedd89 100644 --- a/manila/spec/classes/manila_spec.rb +++ b/manila/spec/classes/manila_spec.rb @@ -13,6 +13,7 @@ req_params end + it { is_expected.to contain_class('manila::logging') } it { is_expected.to contain_class('manila::params') } it { is_expected.to contain_class('mysql::bindings::python') } @@ -246,42 +247,6 @@ end end - describe 'with syslog disabled' do - let :params do - req_params - end - - it { is_expected.to contain_manila_config('DEFAULT/use_syslog').with_value(false) } - end - - describe 'with syslog enabled' do - let :params do - req_params.merge({ - :use_syslog => 'true', - }) - end - - it { is_expected.to contain_manila_config('DEFAULT/use_syslog').with_value(true) } - it { is_expected.to contain_manila_config('DEFAULT/syslog_log_facility').with_value('LOG_USER') } - end - - describe 'with syslog enabled and custom settings' do - let :params do - req_params.merge({ - :use_syslog => 'true', - :log_facility => 'LOG_LOCAL0' - }) - end - - it { is_expected.to contain_manila_config('DEFAULT/use_syslog').with_value(true) } - it { is_expected.to contain_manila_config('DEFAULT/syslog_log_facility').with_value('LOG_LOCAL0') } - end - - describe 'with log_dir disabled' do - let(:params) { req_params.merge!({:log_dir => false}) } - it { is_expected.to contain_manila_config('DEFAULT/log_dir').with_ensure('absent') } - end - describe 'with amqp_durable_queues disabled' do let :params do req_params diff --git a/mysql/Gemfile b/mysql/Gemfile index 1a88250e8..02ae1c310 100644 --- a/mysql/Gemfile +++ b/mysql/Gemfile @@ -14,9 +14,9 @@ group :development, :unit_tests do gem 'rspec-core', '3.1.7', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'simplecov', :require => false - gem 'puppet_facts', :require => false gem 'json', :require => false gem 'metadata-json-lint', :require => false + gem 'rspec-puppet-facts', :require => false end group :system_tests do diff --git a/mysql/manifests/server/root_password.pp b/mysql/manifests/server/root_password.pp index 58aaf495f..9ebc10398 100644 --- a/mysql/manifests/server/root_password.pp +++ b/mysql/manifests/server/root_password.pp @@ -35,7 +35,7 @@ } # show_diff was added with puppet 3.0 - if versioncmp($::puppetversion, '3.0') <= 0 { + if versioncmp($::puppetversion, '3.0') >= 0 { File["${::root_home}/.my.cnf"] { show_diff => false } } if $mysql::server::create_root_user == true { diff --git a/mysql/spec/acceptance/mysql_server_spec.rb b/mysql/spec/acceptance/mysql_server_spec.rb index f41e04cad..e19be5519 100644 --- a/mysql/spec/acceptance/mysql_server_spec.rb +++ b/mysql/spec/acceptance/mysql_server_spec.rb @@ -64,5 +64,21 @@ class { 'mysql::server': apply_manifest(pp, :catch_changes => true) end end -end + describe 'when changing the password' do + let(:password) { 'THE NEW SECRET' } + let(:manifest) { "class { 'mysql::server': root_password => '#{password}' }" } + + it 'should not display the password' do + result = apply_manifest(manifest, :expect_changes => true) + # this does not actually prove anything, as show_diff in the puppet config defaults to false. + expect(result.stdout).not_to match /#{password}/ + end + + it 'should be idempotent' do + result = apply_manifest(manifest, :catch_changes => true) + end + + end + +end diff --git a/mysql/spec/classes/graceful_failures_spec.rb b/mysql/spec/classes/graceful_failures_spec.rb index 7f0781bcc..9fb811786 100644 --- a/mysql/spec/classes/graceful_failures_spec.rb +++ b/mysql/spec/classes/graceful_failures_spec.rb @@ -1,15 +1,19 @@ require 'spec_helper' describe 'mysql::server' do - on_pe_unsupported_platforms.each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + context "on an unsupported OS" do + # fetch any sets of facts to modify them + os, facts = on_supported_os.first - context 'should gracefully fail' do - it { expect { is_expected.to compile}.to raise_error(Puppet::Error, /Unsupported platform:/) } - end - end + let(:facts) { + facts.merge({ + :osfamily => 'UNSUPPORTED', + :operatingsystem => 'UNSUPPORTED', + }) + } + + it 'should gracefully fail' do + is_expected.to compile.and_raise_error(/Unsupported platform:/) end end end diff --git a/mysql/spec/classes/mycnf_template_spec.rb b/mysql/spec/classes/mycnf_template_spec.rb index e6f3c16d4..6446c90f9 100644 --- a/mysql/spec/classes/mycnf_template_spec.rb +++ b/mysql/spec/classes/mycnf_template_spec.rb @@ -2,76 +2,78 @@ describe 'mysql::server' do context 'my.cnf template' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - context 'normal entry' do - let(:params) {{ :override_options => { 'mysqld' => { 'socket' => '/var/lib/mysql/mysql.sock' } } }} - it do - is_expected.to contain_file('mysql-config-file').with({ - :mode => '0644', - :selinux_ignore_defaults => true, - }).with_content(/socket = \/var\/lib\/mysql\/mysql.sock/) - end - end - - describe 'array entry' do - let(:params) {{ :override_options => { 'mysqld' => { 'replicate-do-db' => ['base1', 'base2'], } }}} - it do - is_expected.to contain_file('mysql-config-file').with_content( - /.*replicate-do-db = base1\nreplicate-do-db = base2.*/ - ) - end + context 'normal entry' do + let(:params) {{ :override_options => { 'mysqld' => { 'socket' => '/var/lib/mysql/mysql.sock' } } }} + it do + is_expected.to contain_file('mysql-config-file').with({ + :mode => '0644', + :selinux_ignore_defaults => true, + }).with_content(/socket = \/var\/lib\/mysql\/mysql.sock/) end + end - describe 'ssl set to true' do - let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => true }}}} - it { is_expected.to contain_file('mysql-config-file').with_content(/ssl/) } - it { is_expected.to contain_file('mysql-config-file').without_content(/ssl = true/) } + describe 'array entry' do + let(:params) {{ :override_options => { 'mysqld' => { 'replicate-do-db' => ['base1', 'base2'], } }}} + it do + is_expected.to contain_file('mysql-config-file').with_content( + /.*replicate-do-db = base1\nreplicate-do-db = base2.*/ + ) end + end - describe 'ssl set to false' do - let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => false }}}} - it { is_expected.to contain_file('mysql-config-file').with_content(/ssl = false/) } - end + describe 'ssl set to true' do + let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => true }}}} + it { is_expected.to contain_file('mysql-config-file').with_content(/ssl/) } + it { is_expected.to contain_file('mysql-config-file').without_content(/ssl = true/) } + end - # ssl-disable (and ssl) are special cased within mysql. - describe 'possibility of disabling ssl completely' do - let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => true, 'ssl-disable' => true }}}} - it { is_expected.to contain_file('mysql-config-file').without_content(/ssl = true/) } - end + describe 'ssl set to false' do + let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => false }}}} + it { is_expected.to contain_file('mysql-config-file').with_content(/ssl = false/) } + end - describe 'a non ssl option set to true' do - let(:params) {{ :override_options => { 'mysqld' => { 'test' => true }}}} - it { is_expected.to contain_file('mysql-config-file').with_content(/^test$/) } - it { is_expected.to contain_file('mysql-config-file').without_content(/test = true/) } - end + # ssl-disable (and ssl) are special cased within mysql. + describe 'possibility of disabling ssl completely' do + let(:params) {{ :override_options => { 'mysqld' => { 'ssl' => true, 'ssl-disable' => true }}}} + it { is_expected.to contain_file('mysql-config-file').without_content(/ssl = true/) } + end - context 'with includedir' do - let(:params) {{ :includedir => '/etc/my.cnf.d' }} - it 'makes the directory' do - is_expected.to contain_file('/etc/my.cnf.d').with({ - :ensure => :directory, - :mode => '0755', - }) - end + describe 'a non ssl option set to true' do + let(:params) {{ :override_options => { 'mysqld' => { 'test' => true }}}} + it { is_expected.to contain_file('mysql-config-file').with_content(/^test$/) } + it { is_expected.to contain_file('mysql-config-file').without_content(/test = true/) } + end - it { is_expected.to contain_file('mysql-config-file').with_content(/!includedir/) } + context 'with includedir' do + let(:params) {{ :includedir => '/etc/my.cnf.d' }} + it 'makes the directory' do + is_expected.to contain_file('/etc/my.cnf.d').with({ + :ensure => :directory, + :mode => '0755', + }) end - context 'without includedir' do - let(:params) {{ :includedir => '' }} - it 'shouldnt contain the directory' do - is_expected.not_to contain_file('mysql-config-file').with({ - :ensure => :directory, - :mode => '0755', - }) - end + it { is_expected.to contain_file('mysql-config-file').with_content(/!includedir/) } + end - it { is_expected.to contain_file('mysql-config-file').without_content(/!includedir/) } + context 'without includedir' do + let(:params) {{ :includedir => '' }} + it 'shouldnt contain the directory' do + is_expected.not_to contain_file('mysql-config-file').with({ + :ensure => :directory, + :mode => '0755', + }) end + + it { is_expected.to contain_file('mysql-config-file').without_content(/!includedir/) } end end end diff --git a/mysql/spec/classes/mysql_bindings_spec.rb b/mysql/spec/classes/mysql_bindings_spec.rb index 805817956..066e87635 100644 --- a/mysql/spec/classes/mysql_bindings_spec.rb +++ b/mysql/spec/classes/mysql_bindings_spec.rb @@ -1,30 +1,32 @@ require 'spec_helper' describe 'mysql::bindings' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - let(:params) {{ - 'java_enable' => true, - 'perl_enable' => true, - 'php_enable' => true, - 'python_enable' => true, - 'ruby_enable' => true, - 'client_dev' => true, - 'daemon_dev' => true, - 'client_dev_package_name' => 'libmysqlclient-devel', - 'daemon_dev_package_name' => 'mysql-devel', - }} + let(:params) {{ + 'java_enable' => true, + 'perl_enable' => true, + 'php_enable' => true, + 'python_enable' => true, + 'ruby_enable' => true, + 'client_dev' => true, + 'daemon_dev' => true, + 'client_dev_package_name' => 'libmysqlclient-devel', + 'daemon_dev_package_name' => 'mysql-devel', + }} - it { is_expected.to contain_package('mysql-connector-java') } - it { is_expected.to contain_package('perl_mysql') } - it { is_expected.to contain_package('python-mysqldb') } - it { is_expected.to contain_package('ruby_mysql') } - it { is_expected.to contain_package('mysql-client_dev') } - it { is_expected.to contain_package('mysql-daemon_dev') } - end + it { is_expected.to contain_package('mysql-connector-java') } + it { is_expected.to contain_package('perl_mysql') } + it { is_expected.to contain_package('python-mysqldb') } + it { is_expected.to contain_package('ruby_mysql') } + it { is_expected.to contain_package('mysql-client_dev') } + it { is_expected.to contain_package('mysql-daemon_dev') } end end end diff --git a/mysql/spec/classes/mysql_client_spec.rb b/mysql/spec/classes/mysql_client_spec.rb index b2689b581..fdbcc1975 100644 --- a/mysql/spec/classes/mysql_client_spec.rb +++ b/mysql/spec/classes/mysql_client_spec.rb @@ -1,36 +1,38 @@ require 'spec_helper' describe 'mysql::client' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } - - context 'with defaults' do - it { is_expected.not_to contain_class('mysql::bindings') } - it { is_expected.to contain_package('mysql_client') } - end - - context 'with bindings enabled' do - let(:params) {{ :bindings_enable => true }} + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } + + context 'with defaults' do + it { is_expected.not_to contain_class('mysql::bindings') } + it { is_expected.to contain_package('mysql_client') } + end - it { is_expected.to contain_class('mysql::bindings') } - it { is_expected.to contain_package('mysql_client') } - end + context 'with bindings enabled' do + let(:params) {{ :bindings_enable => true }} - context 'with package_manage set to true' do - let(:params) {{ :package_manage => true }} + it { is_expected.to contain_class('mysql::bindings') } + it { is_expected.to contain_package('mysql_client') } + end - it { is_expected.to contain_package('mysql_client') } - end + context 'with package_manage set to true' do + let(:params) {{ :package_manage => true }} - context 'with package_manage set to false' do - let(:params) {{ :package_manage => false }} + it { is_expected.to contain_package('mysql_client') } + end - it { is_expected.not_to contain_package('mysql_client') } - end + context 'with package_manage set to false' do + let(:params) {{ :package_manage => false }} + it { is_expected.not_to contain_package('mysql_client') } end + end end end diff --git a/mysql/spec/classes/mysql_server_account_security_spec.rb b/mysql/spec/classes/mysql_server_account_security_spec.rb index 6f6e73dc0..d45c46e27 100644 --- a/mysql/spec/classes/mysql_server_account_security_spec.rb +++ b/mysql/spec/classes/mysql_server_account_security_spec.rb @@ -1,10 +1,16 @@ require 'spec_helper' describe 'mysql::server::account_security' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts.merge({:fqdn => 'myhost.mydomain', :hostname => 'myhost'}) } + on_supported_os.each do |os, facts| + context "on #{os}" do + context "with fqdn==myhost.mydomain" do + let(:facts) { + facts.merge({ + :root_home => '/root', + :fqdn => 'myhost.mydomain', + :hostname => 'myhost', + }) + } [ 'root@myhost.mydomain', 'root@127.0.0.1', @@ -32,8 +38,14 @@ end end - describe "on #{pe_version} #{pe_platform} with fqdn==localhost" do - let(:facts) { facts.merge({:fqdn => 'localhost', :hostname => 'localhost'}) } + context "with fqdn==localhost" do + let(:facts) { + facts.merge({ + :root_home => '/root', + :fqdn => 'localhost', + :hostname => 'localhost', + }) + } [ 'root@127.0.0.1', 'root@::1', @@ -48,8 +60,14 @@ end end - describe "on #{pe_version} #{pe_platform} with fqdn==localhost.localdomain" do - let(:facts) { facts.merge({:fqdn => 'localhost.localdomain', :hostname => 'localhost'}) } + context "with fqdn==localhost.localdomain" do + let(:facts) { + facts.merge({ + :root_home => '/root', + :fqdn => 'localhost.localdomain', + :hostname => 'localhost', + }) + } [ 'root@127.0.0.1', 'root@::1', diff --git a/mysql/spec/classes/mysql_server_backup_spec.rb b/mysql/spec/classes/mysql_server_backup_spec.rb index 8d199432c..c1bc3745f 100644 --- a/mysql/spec/classes/mysql_server_backup_spec.rb +++ b/mysql/spec/classes/mysql_server_backup_spec.rb @@ -1,400 +1,402 @@ require 'spec_helper' describe 'mysql::server::backup' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } - - let(:default_params) { - { 'backupuser' => 'testuser', - 'backuppassword' => 'testpass', - 'backupdir' => '/tmp', - 'backuprotate' => '25', - 'delete_before_dump' => true, - 'execpath' => '/usr/bin:/usr/sbin:/bin:/sbin:/opt/zimbra/bin', - } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } + + let(:default_params) { + { 'backupuser' => 'testuser', + 'backuppassword' => 'testpass', + 'backupdir' => '/tmp', + 'backuprotate' => '25', + 'delete_before_dump' => true, + 'execpath' => '/usr/bin:/usr/sbin:/bin:/sbin:/opt/zimbra/bin', } + } - context 'standard conditions' do - let(:params) { default_params } + context 'standard conditions' do + let(:params) { default_params } - # Cannot use that_requires here, doesn't work on classes. - it { is_expected.to contain_mysql_user('testuser@localhost').with( - :require => 'Class[Mysql::Server::Root_password]') } + # Cannot use that_requires here, doesn't work on classes. + it { is_expected.to contain_mysql_user('testuser@localhost').with( + :require => 'Class[Mysql::Server::Root_password]') } + it { is_expected.to contain_mysql_grant('testuser@localhost/*.*').with( + :privileges => ['SELECT', 'RELOAD', 'LOCK TABLES', 'SHOW VIEW', 'PROCESS'] + ).that_requires('Mysql_user[testuser@localhost]') } + + context 'with triggers included' do + let(:params) do + { :include_triggers => true }.merge(default_params) + end it { is_expected.to contain_mysql_grant('testuser@localhost/*.*').with( - :privileges => ['SELECT', 'RELOAD', 'LOCK TABLES', 'SHOW VIEW', 'PROCESS'] + :privileges => ['SELECT', 'RELOAD', 'LOCK TABLES', 'SHOW VIEW', 'PROCESS', 'TRIGGER'] ).that_requires('Mysql_user[testuser@localhost]') } + end - context 'with triggers included' do - let(:params) do - { :include_triggers => true }.merge(default_params) - end - it { is_expected.to contain_mysql_grant('testuser@localhost/*.*').with( - :privileges => ['SELECT', 'RELOAD', 'LOCK TABLES', 'SHOW VIEW', 'PROCESS', 'TRIGGER'] - ).that_requires('Mysql_user[testuser@localhost]') } - end + it { is_expected.to contain_cron('mysql-backup').with( + :command => '/usr/local/sbin/mysqlbackup.sh', + :ensure => 'present' + )} + + it { is_expected.to contain_file('mysqlbackup.sh').with( + :path => '/usr/local/sbin/mysqlbackup.sh', + :ensure => 'present' + ) } + + it { is_expected.to contain_file('mysqlbackupdir').with( + :path => '/tmp', + :ensure => 'directory' + )} + + it 'should have compression by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /bzcat -zc/ + ) + end - it { is_expected.to contain_cron('mysql-backup').with( - :command => '/usr/local/sbin/mysqlbackup.sh', - :ensure => 'present' - )} + it 'should skip backing up events table by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="--ignore-table=mysql.event"/ + ) + end - it { is_expected.to contain_file('mysqlbackup.sh').with( - :path => '/usr/local/sbin/mysqlbackup.sh', - :ensure => 'present' - ) } + it 'should not mention triggers by default because file_per_database is false' do + is_expected.to contain_file('mysqlbackup.sh').without_content( + /.*triggers.*/ + ) + end - it { is_expected.to contain_file('mysqlbackupdir').with( - :path => '/tmp', - :ensure => 'directory' - )} + it 'should not mention routines by default because file_per_database is false' do + is_expected.to contain_file('mysqlbackup.sh').without_content( + /.*routines.*/ + ) + end - it 'should have compression by default' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /bzcat -zc/ - ) - end + it 'should have 25 days of rotation' do + # MySQL counts from 0 + is_expected.to contain_file('mysqlbackup.sh').with_content(/.*ROTATE=24.*/) + end - it 'should skip backing up events table by default' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="--ignore-table=mysql.event"/ - ) - end + it 'should have a standard PATH' do + is_expected.to contain_file('mysqlbackup.sh').with_content(%r{PATH=/usr/bin:/usr/sbin:/bin:/sbin:/opt/zimbra/bin}) + end + end - it 'should not mention triggers by default because file_per_database is false' do - is_expected.to contain_file('mysqlbackup.sh').without_content( - /.*triggers.*/ - ) - end + context 'custom ownership and mode for backupdir' do + let(:params) do + { :backupdirmode => '0750', + :backupdirowner => 'testuser', + :backupdirgroup => 'testgrp', + }.merge(default_params) + end - it 'should not mention routines by default because file_per_database is false' do - is_expected.to contain_file('mysqlbackup.sh').without_content( - /.*routines.*/ - ) - end + it { is_expected.to contain_file('mysqlbackupdir').with( + :path => '/tmp', + :ensure => 'directory', + :mode => '0750', + :owner => 'testuser', + :group => 'testgrp' + ) } + end - it 'should have 25 days of rotation' do - # MySQL counts from 0 - is_expected.to contain_file('mysqlbackup.sh').with_content(/.*ROTATE=24.*/) - end + context 'with compression disabled' do + let(:params) do + { :backupcompress => false }.merge(default_params) + end - it 'should have a standard PATH' do - is_expected.to contain_file('mysqlbackup.sh').with_content(%r{PATH=/usr/bin:/usr/sbin:/bin:/sbin:/opt/zimbra/bin}) - end + it { is_expected.to contain_file('mysqlbackup.sh').with( + :path => '/usr/local/sbin/mysqlbackup.sh', + :ensure => 'present' + ) } + + it 'should be able to disable compression' do + is_expected.to contain_file('mysqlbackup.sh').without_content( + /.*bzcat -zc.*/ + ) end + end - context 'custom ownership and mode for backupdir' do - let(:params) do - { :backupdirmode => '0750', - :backupdirowner => 'testuser', - :backupdirgroup => 'testgrp', - }.merge(default_params) - end + context 'with mysql.events backedup' do + let(:params) do + { :ignore_events => false }.merge(default_params) + end + + it { is_expected.to contain_file('mysqlbackup.sh').with( + :path => '/usr/local/sbin/mysqlbackup.sh', + :ensure => 'present' + ) } - it { is_expected.to contain_file('mysqlbackupdir').with( - :path => '/tmp', - :ensure => 'directory', - :mode => '0750', - :owner => 'testuser', - :group => 'testgrp' - ) } + it 'should be able to backup events table' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="--events"/ + ) end + end - context 'with compression disabled' do - let(:params) do - { :backupcompress => false }.merge(default_params) - end + context 'with database list specified' do + let(:params) do + { :backupdatabases => ['mysql'] }.merge(default_params) + end - it { is_expected.to contain_file('mysqlbackup.sh').with( - :path => '/usr/local/sbin/mysqlbackup.sh', - :ensure => 'present' - ) } + it { is_expected.to contain_file('mysqlbackup.sh').with( + :path => '/usr/local/sbin/mysqlbackup.sh', + :ensure => 'present' + ) + } - it 'should be able to disable compression' do - is_expected.to contain_file('mysqlbackup.sh').without_content( - /.*bzcat -zc.*/ - ) - end + it 'should have a backup file for each database' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /mysql | bzcat -zc \${DIR}\\\${PREFIX}mysql_`date'/ + ) + end + + it 'should skip backup triggers by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ + ) end - context 'with mysql.events backedup' do + it 'should skip backing up routines by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ + ) + end + + context 'with include_triggers set to true' do let(:params) do - { :ignore_events => false }.merge(default_params) + default_params.merge({ + :backupdatabases => ['mysql'], + :include_triggers => true + }) end - it { is_expected.to contain_file('mysqlbackup.sh').with( - :path => '/usr/local/sbin/mysqlbackup.sh', - :ensure => 'present' - ) } - - it 'should be able to backup events table' do + it 'should backup triggers when asked' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="--events"/ + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --triggers"/ ) end end - context 'with database list specified' do + context 'with include_triggers set to false' do let(:params) do - { :backupdatabases => ['mysql'] }.merge(default_params) + default_params.merge({ + :backupdatabases => ['mysql'], + :include_triggers => false + }) end - it { is_expected.to contain_file('mysqlbackup.sh').with( - :path => '/usr/local/sbin/mysqlbackup.sh', - :ensure => 'present' - ) - } - - it 'should have a backup file for each database' do + it 'should skip backing up triggers when asked to skip' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /mysql | bzcat -zc \${DIR}\\\${PREFIX}mysql_`date'/ + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ ) end + end - it 'should skip backup triggers by default' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ - ) + context 'with include_routines set to true' do + let(:params) do + default_params.merge({ + :backupdatabases => ['mysql'], + :include_routines => true + }) end - it 'should skip backing up routines by default' do + it 'should backup routines when asked' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --routines"/ ) end + end - context 'with include_triggers set to true' do - let(:params) do - default_params.merge({ - :backupdatabases => ['mysql'], - :include_triggers => true - }) - end - - it 'should backup triggers when asked' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --triggers"/ - ) - end + context 'with include_routines set to false' do + let(:params) do + default_params.merge({ + :backupdatabases => ['mysql'], + :include_triggers => true + }) end - context 'with include_triggers set to false' do - let(:params) do - default_params.merge({ - :backupdatabases => ['mysql'], - :include_triggers => false - }) - end - - it 'should skip backing up triggers when asked to skip' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ - ) - end + it 'should skip backing up routines when asked to skip' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ + ) end + end + end - context 'with include_routines set to true' do - let(:params) do - default_params.merge({ - :backupdatabases => ['mysql'], - :include_routines => true - }) - end - - it 'should backup routines when asked' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --routines"/ - ) - end - end + context 'with file per database' do + let(:params) do + default_params.merge({ :file_per_database => true }) + end - context 'with include_routines set to false' do - let(:params) do - default_params.merge({ - :backupdatabases => ['mysql'], - :include_triggers => true - }) - end - - it 'should skip backing up routines when asked to skip' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ - ) - end - end + it 'should loop through backup all databases' do + is_expected.to contain_file('mysqlbackup.sh').with_content(/.*SHOW DATABASES.*/) end - context 'with file per database' do + context 'with compression disabled' do let(:params) do - default_params.merge({ :file_per_database => true }) - end - - it 'should loop through backup all databases' do - is_expected.to contain_file('mysqlbackup.sh').with_content(/.*SHOW DATABASES.*/) - end - - context 'with compression disabled' do - let(:params) do - default_params.merge({ :file_per_database => true, :backupcompress => false }) - end - - it 'should loop through backup all databases without compression' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /.*SHOW DATABASES.*/ - ) - is_expected.to contain_file('mysqlbackup.sh').without_content( - /.*bzcat -zc.*/ - ) - end + default_params.merge({ :file_per_database => true, :backupcompress => false }) end - it 'should skip backup triggers by default' do + it 'should loop through backup all databases without compression' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ + /.*SHOW DATABASES.*/ ) - end - - it 'should skip backing up routines by default' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ + is_expected.to contain_file('mysqlbackup.sh').without_content( + /.*bzcat -zc.*/ ) end + end + + it 'should skip backup triggers by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ + ) + end - context 'with include_triggers set to true' do - let(:params) do - default_params.merge({ - :file_per_database => true, - :include_triggers => true - }) - end - - it 'should backup triggers when asked' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --triggers"/ - ) - end + it 'should skip backing up routines by default' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ + ) + end + + context 'with include_triggers set to true' do + let(:params) do + default_params.merge({ + :file_per_database => true, + :include_triggers => true + }) end - context 'with include_triggers set to false' do - let(:params) do - default_params.merge({ - :file_per_database => true, - :include_triggers => false - }) - end - - it 'should skip backing up triggers when asked to skip' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ - ) - end + it 'should backup triggers when asked' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --triggers"/ + ) end + end - context 'with include_routines set to true' do - let(:params) do - default_params.merge({ - :file_per_database => true, - :include_routines => true - }) - end - - it 'should backup routines when asked' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --routines"/ - ) - end + context 'with include_triggers set to false' do + let(:params) do + default_params.merge({ + :file_per_database => true, + :include_triggers => false + }) end - context 'with include_routines set to false' do - let(:params) do - default_params.merge({ - :file_per_database => true, - :include_triggers => true - }) - end - - it 'should skip backing up routines when asked to skip' do - is_expected.to contain_file('mysqlbackup.sh').with_content( - /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ - ) - end + it 'should skip backing up triggers when asked to skip' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-triggers"/ + ) end end - context 'with postscript' do + context 'with include_routines set to true' do let(:params) do - default_params.merge({ :postscript => 'rsync -a /tmp backup01.local-lan:' }) + default_params.merge({ + :file_per_database => true, + :include_routines => true + }) end - it 'should be add postscript' do + it 'should backup routines when asked' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /rsync -a \/tmp backup01.local-lan:/ + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --routines"/ ) end end - context 'with postscripts' do + context 'with include_routines set to false' do let(:params) do - default_params.merge({ :postscript => [ - 'rsync -a /tmp backup01.local-lan:', - 'rsync -a /tmp backup02.local-lan:', - ]}) + default_params.merge({ + :file_per_database => true, + :include_triggers => true + }) end - it 'should be add postscript' do + it 'should skip backing up routines when asked to skip' do is_expected.to contain_file('mysqlbackup.sh').with_content( - /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ + /ADDITIONAL_OPTIONS="\$ADDITIONAL_OPTIONS --skip-routines"/ ) end end + end + + context 'with postscript' do + let(:params) do + default_params.merge({ :postscript => 'rsync -a /tmp backup01.local-lan:' }) + end - context 'with the xtrabackup provider' do + it 'should be add postscript' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /rsync -a \/tmp backup01.local-lan:/ + ) + end + end + + context 'with postscripts' do + let(:params) do + default_params.merge({ :postscript => [ + 'rsync -a /tmp backup01.local-lan:', + 'rsync -a /tmp backup02.local-lan:', + ]}) + end + + it 'should be add postscript' do + is_expected.to contain_file('mysqlbackup.sh').with_content( + /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ + ) + end + end + + context 'with the xtrabackup provider' do + let(:params) do + default_params.merge({:provider => 'xtrabackup'}) + end + + it 'should contain the wrapper script' do + is_expected.to contain_file('xtrabackup.sh').with_content( + /^innobackupex\s+"\$@"/ + ) + end + + context 'with prescript defined' do let(:params) do - default_params.merge({:provider => 'xtrabackup'}) + default_params.merge({ + :provider => 'xtrabackup', + :prescript => [ + 'rsync -a /tmp backup01.local-lan:', + 'rsync -a /tmp backup02.local-lan:', + ] + }) end - it 'should contain the wrapper script' do + it 'should contain the prescript' do is_expected.to contain_file('xtrabackup.sh').with_content( - /^innobackupex\s+"\$@"/ + /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ ) end + end - context 'with prescript defined' do - let(:params) do - default_params.merge({ - :provider => 'xtrabackup', - :prescript => [ - 'rsync -a /tmp backup01.local-lan:', - 'rsync -a /tmp backup02.local-lan:', - ] - }) - end - - it 'should contain the prescript' do - is_expected.to contain_file('xtrabackup.sh').with_content( - /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ - ) - end + context 'with postscript defined' do + let(:params) do + default_params.merge({ + :provider => 'xtrabackup', + :postscript => [ + 'rsync -a /tmp backup01.local-lan:', + 'rsync -a /tmp backup02.local-lan:', + ] + }) end - context 'with postscript defined' do - let(:params) do - default_params.merge({ - :provider => 'xtrabackup', - :postscript => [ - 'rsync -a /tmp backup01.local-lan:', - 'rsync -a /tmp backup02.local-lan:', - ] - }) - end - - it 'should contain the prostscript' do - is_expected.to contain_file('xtrabackup.sh').with_content( - /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ - ) - end + it 'should contain the prostscript' do + is_expected.to contain_file('xtrabackup.sh').with_content( + /.*rsync -a \/tmp backup01.local-lan:\n\nrsync -a \/tmp backup02.local-lan:.*/ + ) end end end diff --git a/mysql/spec/classes/mysql_server_monitor_spec.rb b/mysql/spec/classes/mysql_server_monitor_spec.rb index d9eea001d..27fab17d4 100644 --- a/mysql/spec/classes/mysql_server_monitor_spec.rb +++ b/mysql/spec/classes/mysql_server_monitor_spec.rb @@ -1,35 +1,38 @@ require 'spec_helper' describe 'mysql::server::monitor' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } - let :pre_condition do - "include 'mysql::server'" - end + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - let :default_params do - { - :mysql_monitor_username => 'monitoruser', - :mysql_monitor_password => 'monitorpass', - :mysql_monitor_hostname => 'monitorhost', - } - end - - let :params do - default_params - end + let :pre_condition do + "include 'mysql::server'" + end - it { is_expected.to contain_mysql_user('monitoruser@monitorhost')} + let :default_params do + { + :mysql_monitor_username => 'monitoruser', + :mysql_monitor_password => 'monitorpass', + :mysql_monitor_hostname => 'monitorhost', + } + end - it { is_expected.to contain_mysql_grant('monitoruser@monitorhost/*.*').with( - :ensure => 'present', - :user => 'monitoruser@monitorhost', - :table => '*.*', - :privileges => ["PROCESS", "SUPER"], - :require => 'Mysql_user[monitoruser@monitorhost]' - )} + let :params do + default_params end + + it { is_expected.to contain_mysql_user('monitoruser@monitorhost')} + + it { is_expected.to contain_mysql_grant('monitoruser@monitorhost/*.*').with( + :ensure => 'present', + :user => 'monitoruser@monitorhost', + :table => '*.*', + :privileges => ["PROCESS", "SUPER"], + :require => 'Mysql_user[monitoruser@monitorhost]' + )} end end end diff --git a/mysql/spec/classes/mysql_server_mysqltuner_spec.rb b/mysql/spec/classes/mysql_server_mysqltuner_spec.rb index e8d0c7307..207246af6 100644 --- a/mysql/spec/classes/mysql_server_mysqltuner_spec.rb +++ b/mysql/spec/classes/mysql_server_mysqltuner_spec.rb @@ -1,42 +1,44 @@ require 'spec_helper' describe 'mysql::server::mysqltuner' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - context 'ensure => present' do - it { is_expected.to compile } - it { is_expected.to contain_staging__file('mysqltuner-v1.3.0').with({ - :source => 'https://github.com/major/MySQLTuner-perl/raw/v1.3.0/mysqltuner.pl', - }) - } - end + context 'ensure => present' do + it { is_expected.to compile } + it { is_expected.to contain_staging__file('mysqltuner-v1.3.0').with({ + :source => 'https://github.com/major/MySQLTuner-perl/raw/v1.3.0/mysqltuner.pl', + }) + } + end - context 'ensure => absent' do - let(:params) {{ :ensure => 'absent' }} - it { is_expected.to compile } - it { is_expected.to contain_file('/usr/local/bin/mysqltuner').with(:ensure => 'absent') } - end + context 'ensure => absent' do + let(:params) {{ :ensure => 'absent' }} + it { is_expected.to compile } + it { is_expected.to contain_file('/usr/local/bin/mysqltuner').with(:ensure => 'absent') } + end - context 'custom version' do - let(:params) {{ :version => 'v1.2.0' }} - it { is_expected.to compile } - it { is_expected.to contain_staging__file('mysqltuner-v1.2.0').with({ - :source => 'https://github.com/major/MySQLTuner-perl/raw/v1.2.0/mysqltuner.pl', - }) - } - end + context 'custom version' do + let(:params) {{ :version => 'v1.2.0' }} + it { is_expected.to compile } + it { is_expected.to contain_staging__file('mysqltuner-v1.2.0').with({ + :source => 'https://github.com/major/MySQLTuner-perl/raw/v1.2.0/mysqltuner.pl', + }) + } + end - context 'custom source' do - let(:params) {{ :source => '/tmp/foo' }} - it { is_expected.to compile } - it { is_expected.to contain_staging__file('mysqltuner-/tmp/foo').with({ - :source => '/tmp/foo', - }) - } - end + context 'custom source' do + let(:params) {{ :source => '/tmp/foo' }} + it { is_expected.to compile } + it { is_expected.to contain_staging__file('mysqltuner-/tmp/foo').with({ + :source => '/tmp/foo', + }) + } end end end diff --git a/mysql/spec/classes/mysql_server_spec.rb b/mysql/spec/classes/mysql_server_spec.rb index e5909f457..0625895ee 100644 --- a/mysql/spec/classes/mysql_server_spec.rb +++ b/mysql/spec/classes/mysql_server_spec.rb @@ -1,190 +1,200 @@ require 'spec_helper' describe 'mysql::server' do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - context 'with defaults' do - it { is_expected.to contain_class('mysql::server::install') } - it { is_expected.to contain_class('mysql::server::config') } - it { is_expected.to contain_class('mysql::server::service') } - it { is_expected.to contain_class('mysql::server::root_password') } - it { is_expected.to contain_class('mysql::server::providers') } - end + context 'with defaults' do + it { is_expected.to contain_class('mysql::server::install') } + it { is_expected.to contain_class('mysql::server::config') } + it { is_expected.to contain_class('mysql::server::service') } + it { is_expected.to contain_class('mysql::server::root_password') } + it { is_expected.to contain_class('mysql::server::providers') } + end + + context 'with remove_default_accounts set' do + let(:params) {{ :remove_default_accounts => true }} + it { is_expected.to contain_class('mysql::server::account_security') } + end - context 'with remove_default_accounts set' do - let(:params) {{ :remove_default_accounts => true }} - it { is_expected.to contain_class('mysql::server::account_security') } + context 'when not managing config file' do + let(:params) {{ :manage_config_file => false }} + it { is_expected.to compile.with_all_deps } + end + + context 'mysql::server::install' do + it 'contains the package by default' do + is_expected.to contain_package('mysql-server').with({ + :ensure => :present, + }) + end + context 'with package_manage set to true' do + let(:params) {{ :package_manage => true }} + it { is_expected.to contain_package('mysql-server') } + end + context 'with package_manage set to false' do + let(:params) {{ :package_manage => false }} + it { is_expected.not_to contain_package('mysql-server') } + end + context 'with datadir overridden' do + let(:params) {{ :override_options => { 'mysqld' => { 'datadir' => '/tmp' }} }} + it { is_expected.to contain_exec('mysql_install_db') } end + end - context 'when not managing config file' do - let(:params) {{ :manage_config_file => false }} - it { is_expected.to compile.with_all_deps } + context 'mysql::server::service' do + context 'with defaults' do + it { is_expected.to contain_service('mysqld') } + end + context 'with package_manage set to true' do + let(:params) {{ :package_manage => true }} + it { is_expected.to contain_service('mysqld').that_requires('Package[mysql-server]') } end + context 'with package_manage set to false' do + let(:params) {{ :package_manage => false }} + it { is_expected.to contain_service('mysqld') } + it { is_expected.not_to contain_service('mysqld').that_requires('Package[mysql-server]') } + end + context 'service_enabled set to false' do + let(:params) {{ :service_enabled => false }} - context 'mysql::server::install' do - it 'contains the package by default' do - is_expected.to contain_package('mysql-server').with({ - :ensure => :present, + it do + is_expected.to contain_service('mysqld').with({ + :ensure => :stopped }) end - context 'with package_manage set to true' do - let(:params) {{ :package_manage => true }} - it { is_expected.to contain_package('mysql-server') } - end - context 'with package_manage set to false' do - let(:params) {{ :package_manage => false }} - it { is_expected.not_to contain_package('mysql-server') } - end - context 'with datadir overridden' do - let(:params) {{ :override_options => { 'mysqld' => { 'datadir' => '/tmp' }} }} - it { is_expected.to contain_exec('mysql_install_db') } - end end - - context 'mysql::server::service' do - context 'with defaults' do - it { is_expected.to contain_service('mysqld') } - end - context 'with package_manage set to true' do - let(:params) {{ :package_manage => true }} - it { is_expected.to contain_service('mysqld').that_requires('Package[mysql-server]') } - end - context 'with package_manage set to false' do - let(:params) {{ :package_manage => false }} - it { is_expected.to contain_service('mysqld') } - it { is_expected.not_to contain_service('mysqld').that_requires('Package[mysql-server]') } - end - context 'service_enabled set to false' do - let(:params) {{ :service_enabled => false }} - - it do - is_expected.to contain_service('mysqld').with({ - :ensure => :stopped - }) - end - end - context 'with log-error overridden' do - let(:params) {{ :override_options => { 'mysqld' => { 'log-error' => '/tmp/error.log' }} }} - it { is_expected.to contain_file('/tmp/error.log') } - end + context 'with log-error overridden' do + let(:params) {{ :override_options => { 'mysqld' => { 'log-error' => '/tmp/error.log' }} }} + it { is_expected.to contain_file('/tmp/error.log') } end + end - context 'mysql::server::root_password' do - describe 'when defaults' do - it { - is_expected.to contain_exec('remove install pass').with( - :command => 'mysqladmin -u root --password=$(grep -o \'[^ ]\\+$\' /.mysql_secret) password \'\' && rm -f /.mysql_secret', - :onlyif => 'test -f /.mysql_secret', - :path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin' - ) - } - it { is_expected.not_to contain_mysql_user('root@localhost') } - it { is_expected.not_to contain_file('/root/.my.cnf') } - end - describe 'when root_password set' do - let(:params) {{:root_password => 'SET' }} - it { is_expected.to contain_mysql_user('root@localhost') } + context 'mysql::server::root_password' do + describe 'when defaults' do + it { + is_expected.to contain_exec('remove install pass').with( + :command => 'mysqladmin -u root --password=$(grep -o \'[^ ]\\+$\' /.mysql_secret) password \'\' && rm -f /.mysql_secret', + :onlyif => 'test -f /.mysql_secret', + :path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin' + ) + } + it { is_expected.not_to contain_mysql_user('root@localhost') } + it { is_expected.not_to contain_file('/root/.my.cnf') } + end + describe 'when root_password set' do + let(:params) {{:root_password => 'SET' }} + it { is_expected.to contain_mysql_user('root@localhost') } + if Puppet.version.to_f >= 3.0 + it { is_expected.to contain_file('/root/.my.cnf').with(:show_diff => false).that_requires('Mysql_user[root@localhost]') } + else it { is_expected.to contain_file('/root/.my.cnf').that_requires('Mysql_user[root@localhost]') } end - describe 'when root_password set, create_root_user set to false' do - let(:params) {{ :root_password => 'SET', :create_root_user => false }} - it { is_expected.not_to contain_mysql_user('root@localhost') } + end + describe 'when root_password set, create_root_user set to false' do + let(:params) {{ :root_password => 'SET', :create_root_user => false }} + it { is_expected.not_to contain_mysql_user('root@localhost') } + if Puppet.version.to_f >= 3.0 + it { is_expected.to contain_file('/root/.my.cnf').with(:show_diff => false) } + else it { is_expected.to contain_file('/root/.my.cnf') } end - describe 'when root_password set, create_root_my_cnf set to false' do - let(:params) {{ :root_password => 'SET', :create_root_my_cnf => false }} - it { is_expected.to contain_mysql_user('root@localhost') } - it { is_expected.not_to contain_file('/root/.my.cnf') } - end - describe 'when root_password set, create_root_user and create_root_my_cnf set to false' do - let(:params) {{ :root_password => 'SET', :create_root_user => false, :create_root_my_cnf => false }} - it { is_expected.not_to contain_mysql_user('root@localhost') } - it { is_expected.not_to contain_file('/root/.my.cnf') } - end - describe 'when install_secret_file set to /root/.mysql_secret' do - let(:params) {{ :install_secret_file => '/root/.mysql_secret' }} - it { - is_expected.to contain_exec('remove install pass').with( - :command => 'mysqladmin -u root --password=$(grep -o \'[^ ]\\+$\' /root/.mysql_secret) password \'\' && rm -f /root/.mysql_secret', - :onlyif => 'test -f /root/.mysql_secret' - ) - } - end end + describe 'when root_password set, create_root_my_cnf set to false' do + let(:params) {{ :root_password => 'SET', :create_root_my_cnf => false }} + it { is_expected.to contain_mysql_user('root@localhost') } + it { is_expected.not_to contain_file('/root/.my.cnf') } + end + describe 'when root_password set, create_root_user and create_root_my_cnf set to false' do + let(:params) {{ :root_password => 'SET', :create_root_user => false, :create_root_my_cnf => false }} + it { is_expected.not_to contain_mysql_user('root@localhost') } + it { is_expected.not_to contain_file('/root/.my.cnf') } + end + describe 'when install_secret_file set to /root/.mysql_secret' do + let(:params) {{ :install_secret_file => '/root/.mysql_secret' }} + it { + is_expected.to contain_exec('remove install pass').with( + :command => 'mysqladmin -u root --password=$(grep -o \'[^ ]\\+$\' /root/.mysql_secret) password \'\' && rm -f /root/.mysql_secret', + :onlyif => 'test -f /root/.mysql_secret' + ) + } + end + end - context 'mysql::server::providers' do - describe 'with users' do - let(:params) {{:users => { - 'foo@localhost' => { - 'max_connections_per_hour' => '1', - 'max_queries_per_hour' => '2', - 'max_updates_per_hour' => '3', - 'max_user_connections' => '4', - 'password_hash' => '*F3A2A51A9B0F2BE2468926B4132313728C250DBF' - }, - 'foo2@localhost' => {} - }}} - it { is_expected.to contain_mysql_user('foo@localhost').with( - :max_connections_per_hour => '1', - :max_queries_per_hour => '2', - :max_updates_per_hour => '3', - :max_user_connections => '4', - :password_hash => '*F3A2A51A9B0F2BE2468926B4132313728C250DBF' - )} - it { is_expected.to contain_mysql_user('foo2@localhost').with( - :max_connections_per_hour => nil, - :max_queries_per_hour => nil, - :max_updates_per_hour => nil, - :max_user_connections => nil, - :password_hash => nil - )} - end + context 'mysql::server::providers' do + describe 'with users' do + let(:params) {{:users => { + 'foo@localhost' => { + 'max_connections_per_hour' => '1', + 'max_queries_per_hour' => '2', + 'max_updates_per_hour' => '3', + 'max_user_connections' => '4', + 'password_hash' => '*F3A2A51A9B0F2BE2468926B4132313728C250DBF' + }, + 'foo2@localhost' => {} + }}} + it { is_expected.to contain_mysql_user('foo@localhost').with( + :max_connections_per_hour => '1', + :max_queries_per_hour => '2', + :max_updates_per_hour => '3', + :max_user_connections => '4', + :password_hash => '*F3A2A51A9B0F2BE2468926B4132313728C250DBF' + )} + it { is_expected.to contain_mysql_user('foo2@localhost').with( + :max_connections_per_hour => nil, + :max_queries_per_hour => nil, + :max_updates_per_hour => nil, + :max_user_connections => nil, + :password_hash => nil + )} + end - describe 'with grants' do - let(:params) {{:grants => { - 'foo@localhost/somedb.*' => { - 'user' => 'foo@localhost', - 'table' => 'somedb.*', - 'privileges' => ["SELECT", "UPDATE"], - 'options' => ["GRANT"], - }, - 'foo2@localhost/*.*' => { - 'user' => 'foo2@localhost', - 'table' => '*.*', - 'privileges' => ["SELECT"], - }, - }}} - it { is_expected.to contain_mysql_grant('foo@localhost/somedb.*').with( - :user => 'foo@localhost', - :table => 'somedb.*', - :privileges => ["SELECT", "UPDATE"], - :options => ["GRANT"] - )} - it { is_expected.to contain_mysql_grant('foo2@localhost/*.*').with( - :user => 'foo2@localhost', - :table => '*.*', - :privileges => ["SELECT"], - :options => nil - )} - end + describe 'with grants' do + let(:params) {{:grants => { + 'foo@localhost/somedb.*' => { + 'user' => 'foo@localhost', + 'table' => 'somedb.*', + 'privileges' => ["SELECT", "UPDATE"], + 'options' => ["GRANT"], + }, + 'foo2@localhost/*.*' => { + 'user' => 'foo2@localhost', + 'table' => '*.*', + 'privileges' => ["SELECT"], + }, + }}} + it { is_expected.to contain_mysql_grant('foo@localhost/somedb.*').with( + :user => 'foo@localhost', + :table => 'somedb.*', + :privileges => ["SELECT", "UPDATE"], + :options => ["GRANT"] + )} + it { is_expected.to contain_mysql_grant('foo2@localhost/*.*').with( + :user => 'foo2@localhost', + :table => '*.*', + :privileges => ["SELECT"], + :options => nil + )} + end - describe 'with databases' do - let(:params) {{:databases => { - 'somedb' => { - 'charset' => 'latin1', - 'collate' => 'latin1', - }, - 'somedb2' => {} - }}} - it { is_expected.to contain_mysql_database('somedb').with( - :charset => 'latin1', - :collate => 'latin1' - )} - it { is_expected.to contain_mysql_database('somedb2')} - end + describe 'with databases' do + let(:params) {{:databases => { + 'somedb' => { + 'charset' => 'latin1', + 'collate' => 'latin1', + }, + 'somedb2' => {} + }}} + it { is_expected.to contain_mysql_database('somedb').with( + :charset => 'latin1', + :collate => 'latin1' + )} + it { is_expected.to contain_mysql_database('somedb2')} end end end diff --git a/mysql/spec/defines/mysql_db_spec.rb b/mysql/spec/defines/mysql_db_spec.rb index 7ff3b9c38..15c00f653 100644 --- a/mysql/spec/defines/mysql_db_spec.rb +++ b/mysql/spec/defines/mysql_db_spec.rb @@ -1,74 +1,76 @@ require 'spec_helper' describe 'mysql::db', :type => :define do - on_pe_supported_platforms(PLATFORMS).each do |pe_version,pe_platforms| - pe_platforms.each do |pe_platform,facts| - describe "on #{pe_version} #{pe_platform}" do - let(:facts) { facts } + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { + facts.merge({ + :root_home => '/root', + }) + } - let(:title) { 'test_db' } + let(:title) { 'test_db' } - let(:params) { - { 'user' => 'testuser', - 'password' => 'testpass', - } + let(:params) { + { 'user' => 'testuser', + 'password' => 'testpass', } + } - it 'should report an error when ensure is not present or absent' do - params.merge!({'ensure' => 'invalid_val'}) - expect { catalogue }.to raise_error(Puppet::Error, - /invalid_val is not supported for ensure\. Allowed values are 'present' and 'absent'\./) - end + it 'should report an error when ensure is not present or absent' do + params.merge!({'ensure' => 'invalid_val'}) + expect { catalogue }.to raise_error(Puppet::Error, + /invalid_val is not supported for ensure\. Allowed values are 'present' and 'absent'\./) + end - it 'should not notify the import sql exec if no sql script was provided' do - is_expected.to contain_mysql_database('test_db').without_notify - end + it 'should not notify the import sql exec if no sql script was provided' do + is_expected.to contain_mysql_database('test_db').without_notify + end - it 'should subscribe to database if sql script is given' do - params.merge!({'sql' => 'test_sql'}) - is_expected.to contain_exec('test_db-import').with_subscribe('Mysql_database[test_db]') - end + it 'should subscribe to database if sql script is given' do + params.merge!({'sql' => 'test_sql'}) + is_expected.to contain_exec('test_db-import').with_subscribe('Mysql_database[test_db]') + end - it 'should only import sql script on creation if not enforcing' do - params.merge!({'sql' => 'test_sql', 'enforce_sql' => false}) - is_expected.to contain_exec('test_db-import').with_refreshonly(true) - end + it 'should only import sql script on creation if not enforcing' do + params.merge!({'sql' => 'test_sql', 'enforce_sql' => false}) + is_expected.to contain_exec('test_db-import').with_refreshonly(true) + end - it 'should import sql script on creation if enforcing' do - params.merge!({'sql' => 'test_sql', 'enforce_sql' => true}) - is_expected.to contain_exec('test_db-import').with_refreshonly(false) - is_expected.to contain_exec('test_db-import').with_command("cat test_sql | mysql test_db") - end + it 'should import sql script on creation if enforcing' do + params.merge!({'sql' => 'test_sql', 'enforce_sql' => true}) + is_expected.to contain_exec('test_db-import').with_refreshonly(false) + is_expected.to contain_exec('test_db-import').with_command("cat test_sql | mysql test_db") + end - it 'should import sql scripts when more than one is specified' do - params.merge!({'sql' => ['test_sql', 'test_2_sql']}) - is_expected.to contain_exec('test_db-import').with_command('cat test_sql test_2_sql | mysql test_db') - end + it 'should import sql scripts when more than one is specified' do + params.merge!({'sql' => ['test_sql', 'test_2_sql']}) + is_expected.to contain_exec('test_db-import').with_command('cat test_sql test_2_sql | mysql test_db') + end - it 'should report an error if sql isn\'t a string or an array' do - params.merge!({'sql' => {'foo' => 'test_sql', 'bar' => 'test_2_sql'}}) - expect { catalogue }.to raise_error(Puppet::Error, - /\$sql must be either a string or an array\./) - end + it 'should report an error if sql isn\'t a string or an array' do + params.merge!({'sql' => {'foo' => 'test_sql', 'bar' => 'test_2_sql'}}) + expect { catalogue }.to raise_error(Puppet::Error, + /\$sql must be either a string or an array\./) + end - it 'should not create database and database user' do - params.merge!({'ensure' => 'absent', 'host' => 'localhost'}) - is_expected.to contain_mysql_database('test_db').with_ensure('absent') - is_expected.to contain_mysql_user('testuser@localhost').with_ensure('absent') - end + it 'should not create database and database user' do + params.merge!({'ensure' => 'absent', 'host' => 'localhost'}) + is_expected.to contain_mysql_database('test_db').with_ensure('absent') + is_expected.to contain_mysql_user('testuser@localhost').with_ensure('absent') + end - it 'should create with an appropriate collate and charset' do - params.merge!({'charset' => 'utf8', 'collate' => 'utf8_danish_ci'}) - is_expected.to contain_mysql_database('test_db').with({ - 'charset' => 'utf8', - 'collate' => 'utf8_danish_ci', - }) - end + it 'should create with an appropriate collate and charset' do + params.merge!({'charset' => 'utf8', 'collate' => 'utf8_danish_ci'}) + is_expected.to contain_mysql_database('test_db').with({ + 'charset' => 'utf8', + 'collate' => 'utf8_danish_ci', + }) + end - it 'should use dbname parameter as database name instead of name' do - params.merge!({'dbname' => 'real_db'}) - is_expected.to contain_mysql_database('real_db') - end + it 'should use dbname parameter as database name instead of name' do + params.merge!({'dbname' => 'real_db'}) + is_expected.to contain_mysql_database('real_db') end end end diff --git a/mysql/spec/spec_helper.rb b/mysql/spec/spec_helper.rb index be79afe8a..6277b13b6 100644 --- a/mysql/spec/spec_helper.rb +++ b/mysql/spec/spec_helper.rb @@ -1,6 +1,6 @@ require 'puppetlabs_spec_helper/module_spec_helper' -require 'puppet_facts' -include PuppetFacts +require 'rspec-puppet-facts' +include RspecPuppetFacts # The default set of platforms to test again. ENV['UNIT_TEST_PLATFORMS'] = 'centos-6-x86_64 ubuntu-1404-x86_64' diff --git a/neutron/manifests/agents/dhcp.pp b/neutron/manifests/agents/dhcp.pp index 1d1f4979c..0c1049205 100644 --- a/neutron/manifests/agents/dhcp.pp +++ b/neutron/manifests/agents/dhcp.pp @@ -47,7 +47,7 @@ # # [*dhcp_delete_namespaces*] # (optional) Delete namespace after removing a dhcp server -# Defaults to false. +# Defaults to true. # # [*enable_isolated_metadata*] # (optional) enable metadata support on isolated networks. @@ -84,7 +84,7 @@ $dhcp_driver = 'neutron.agent.linux.dhcp.Dnsmasq', $root_helper = 'sudo neutron-rootwrap /etc/neutron/rootwrap.conf', $dnsmasq_config_file = undef, - $dhcp_delete_namespaces = false, + $dhcp_delete_namespaces = true, $enable_isolated_metadata = false, $enable_metadata_network = false, $dhcp_broadcast_reply = false, diff --git a/neutron/manifests/agents/l3.pp b/neutron/manifests/agents/l3.pp index 2c490ad2b..d8a2602a8 100644 --- a/neutron/manifests/agents/l3.pp +++ b/neutron/manifests/agents/l3.pp @@ -70,7 +70,7 @@ # # [*router_delete_namespaces*] # (optional) namespaces can be deleted cleanly on the host running the L3 agent -# Defaults to False +# Defaults to true # # [*ha_enabled*] # (optional) Enabled or not HA for L3 agent. @@ -122,7 +122,7 @@ $periodic_fuzzy_delay = '5', $enable_metadata_proxy = true, $network_device_mtu = undef, - $router_delete_namespaces = false, + $router_delete_namespaces = true, $ha_enabled = false, $ha_vrrp_auth_type = 'PASS', $ha_vrrp_auth_password = undef, diff --git a/neutron/manifests/agents/n1kv_vem.pp b/neutron/manifests/agents/n1kv_vem.pp index 3e2ba6044..cec3d3988 100644 --- a/neutron/manifests/agents/n1kv_vem.pp +++ b/neutron/manifests/agents/n1kv_vem.pp @@ -202,12 +202,14 @@ gpgkey => "${n1kv_source}/RPM-GPG-KEY" #proxy => '_none_', } + warning('cisco-vem-repo repository management is deprecated, it will be dropped in a future release.') } package {'nexus1000v': ensure => $package_ensure, tag => 'openstack', } } + warning('nexus1000v package management is deprecated, it will be dropped in a future release.') if $manage_service { if $enable { @@ -220,6 +222,7 @@ service { 'nexus1000v': ensure => $service_ensure, } + warning('nexus1000v service management is deprecated, it will be dropped in a future release.') #Upon config change in 'n1kv.conf' execute below 'vemcmd reread config'. #No need to restart service. diff --git a/neutron/manifests/db/sync.pp b/neutron/manifests/db/sync.pp index 40d761606..54eb2cb36 100644 --- a/neutron/manifests/db/sync.pp +++ b/neutron/manifests/db/sync.pp @@ -6,7 +6,7 @@ include ::neutron::params Package<| tag == 'neutron-package' |> ~> Exec['neutron-db-sync'] - Exec['neutron-db-sync'] ~> Service <| tag == 'neutron-service' |> + Exec['neutron-db-sync'] ~> Service <| tag == 'neutron-db-sync-service' |> Neutron_config<||> ~> Exec['neutron-db-sync'] Neutron_config<| title == 'database/connection' |> ~> Exec['neutron-db-sync'] diff --git a/neutron/manifests/plugins/ml2/bigswitch.pp b/neutron/manifests/plugins/ml2/bigswitch.pp index 889b00d8e..6a2f23aa4 100644 --- a/neutron/manifests/plugins/ml2/bigswitch.pp +++ b/neutron/manifests/plugins/ml2/bigswitch.pp @@ -26,4 +26,5 @@ tag => 'openstack', } ) + warning('python-networking-bigswitch package management is deprecated, it will be dropped in a future release.') } diff --git a/neutron/manifests/plugins/ml2/cisco.pp b/neutron/manifests/plugins/ml2/cisco.pp index 05ea71499..14a0f488a 100644 --- a/neutron/manifests/plugins/ml2/cisco.pp +++ b/neutron/manifests/plugins/ml2/cisco.pp @@ -28,4 +28,5 @@ tag => 'openstack', } ) + warning('python-networking-cisco package management is deprecated, it will be dropped in a future release.') } diff --git a/neutron/manifests/plugins/plumgrid.pp b/neutron/manifests/plugins/plumgrid.pp index 1310ab046..07376ce8c 100644 --- a/neutron/manifests/plugins/plumgrid.pp +++ b/neutron/manifests/plugins/plumgrid.pp @@ -97,6 +97,7 @@ ensure => $package_ensure, name => $::neutron::params::plumgrid_pythonlib_package } + warning('neutron-plumlib-plumgrid package management is deprecated, it will be dropped in a future release.') if $::osfamily == 'Debian' { file_line { '/etc/default/neutron-server:NEUTRON_PLUGIN_CONFIG': diff --git a/neutron/manifests/server.pp b/neutron/manifests/server.pp index 65921c9e8..8915f5b09 100644 --- a/neutron/manifests/server.pp +++ b/neutron/manifests/server.pp @@ -477,6 +477,6 @@ hasstatus => true, hasrestart => true, require => Class['neutron'], - tag => 'neutron-service', + tag => ['neutron-service', 'neutron-db-sync-service'], } } diff --git a/neutron/spec/classes/neutron_agents_dhcp_spec.rb b/neutron/spec/classes/neutron_agents_dhcp_spec.rb index 0e6d8a1dc..3c38c4615 100644 --- a/neutron/spec/classes/neutron_agents_dhcp_spec.rb +++ b/neutron/spec/classes/neutron_agents_dhcp_spec.rb @@ -22,7 +22,7 @@ :root_helper => 'sudo neutron-rootwrap /etc/neutron/rootwrap.conf', :use_namespaces => nil, :dnsmasq_config_file => nil, - :dhcp_delete_namespaces => false, + :dhcp_delete_namespaces => true, :enable_isolated_metadata => false, :enable_metadata_network => false, :dhcp_broadcast_reply => false } diff --git a/neutron/spec/classes/neutron_agents_l3_spec.rb b/neutron/spec/classes/neutron_agents_l3_spec.rb index 5115331b8..d939deec0 100644 --- a/neutron/spec/classes/neutron_agents_l3_spec.rb +++ b/neutron/spec/classes/neutron_agents_l3_spec.rb @@ -22,7 +22,7 @@ :periodic_fuzzy_delay => '5', :enable_metadata_proxy => true, :network_device_mtu => nil, - :router_delete_namespaces => false, + :router_delete_namespaces => true, :ha_enabled => false, :ha_vrrp_auth_type => 'PASS', :ha_vrrp_auth_password => nil, diff --git a/neutron/spec/classes/neutron_server_spec.rb b/neutron/spec/classes/neutron_server_spec.rb index 0037209b8..acb40efdb 100644 --- a/neutron/spec/classes/neutron_server_spec.rb +++ b/neutron/spec/classes/neutron_server_spec.rb @@ -85,7 +85,7 @@ :enable => true, :ensure => 'running', :require => 'Class[Neutron]', - :tag => 'neutron-service', + :tag => ['neutron-service', 'neutron-db-sync-service'], ) is_expected.not_to contain_class('neutron::db::sync') is_expected.to contain_neutron_api_config('filter:authtoken/auth_admin_prefix').with( diff --git a/redis/manifests/init.pp b/redis/manifests/init.pp index 6b9564d82..a420bddd3 100644 --- a/redis/manifests/init.pp +++ b/redis/manifests/init.pp @@ -279,6 +279,11 @@ # # Default: OS dependant # +# [*service_provider*] +# Specify the service provider to use +# +# Default: undef +# # [*service_user*] # Specify which user to run as. # @@ -426,6 +431,7 @@ $service_hasstatus = $::redis::params::service_hasstatus, $service_manage = $::redis::params::service_manage, $service_name = $::redis::params::service_name, + $service_provider = $::redis::params::service_provider, $service_user = $::redis::params::service_user, $set_max_intset_entries = $::redis::params::set_max_intset_entries, $slave_read_only = $::redis::params::slave_read_only, diff --git a/redis/manifests/params.pp b/redis/manifests/params.pp index 559a968e7..e4d7fc31e 100644 --- a/redis/manifests/params.pp +++ b/redis/manifests/params.pp @@ -52,6 +52,7 @@ $sentinel_init_template = 'redis/redis-sentinel.init.erb' $sentinel_pid_file = '/var/run/redis/redis-sentinel.pid' $sentinel_notification_script = undef + $service_provider = undef $set_max_intset_entries = 512 $slowlog_log_slower_than = 10000 $slowlog_max_len = 1024 diff --git a/redis/manifests/service.pp b/redis/manifests/service.pp index 53ae7ffbf..9d86f0274 100644 --- a/redis/manifests/service.pp +++ b/redis/manifests/service.pp @@ -9,6 +9,7 @@ enable => $::redis::service_enable, hasrestart => $::redis::service_hasrestart, hasstatus => $::redis::service_hasstatus, + provider => $::redis::service_provider, } } } diff --git a/stdlib/README.markdown b/stdlib/README.markdown index d023f2312..f9c942566 100644 --- a/stdlib/README.markdown +++ b/stdlib/README.markdown @@ -76,18 +76,56 @@ The `stdlib::stages` class declares various run stages for deploying infrastruct ### Types #### `file_line` - Ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use `match` to replace existing lines. - ~~~ - file_line { 'sudo_rule': - path => '/etc/sudoers', - line => '%sudo ALL=(ALL) ALL', - } - file_line { 'sudo_rule_nopw': - path => '/etc/sudoers', - line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', - } - ~~~ +Ensures that a given line is contained within a file. The implementation +matches the full line, including whitespace at the beginning and end. If +the line is not contained in the given file, Puppet will append the line to +the end of the file to ensure the desired state. Multiple resources may +be declared to manage multiple lines in the same file. + +Example: + + file_line { 'sudo_rule': + path => '/etc/sudoers', + line => '%sudo ALL=(ALL) ALL', + } + + file_line { 'sudo_rule_nopw': + path => '/etc/sudoers', + line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', + } + +In this example, Puppet will ensure both of the specified lines are +contained in the file /etc/sudoers. + +Match Example: + + file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + } + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and replace it with the value in line. + +Match Example With `ensure => absent`: + + file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + match_for_absence => true, + } + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and delete it. If multiple lines match, an +error will be raised unless the `multiple => true` parameter is set. + +**Autorequires:** If Puppet is managing the file that will contain the line +being managed, the file_line resource will autorequire that file. ##### Parameters All parameters are optional, unless otherwise noted. @@ -95,13 +133,13 @@ All parameters are optional, unless otherwise noted. * `after`: Specifies the line after which Puppet will add any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. -* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. Valid options: String containing a regex. Default: Undefined. +* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value and if it does not match an exception will be raised. Valid options: String containing a regex. Default: Undefined. +* `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Default: false. * `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. * `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. * `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true - ### Functions #### `abs` @@ -132,6 +170,22 @@ Converts a boolean to a number. Converts values: * 'true', 't', '1', 'y', and 'yes' to 1. Requires a single boolean or string as an input. *Type*: rvalue. +#### `bool2str` + +Converts a boolean to a string using optionally supplied arguments. The optional +second and third arguments represent what true and false will be converted to +respectively. If only one argument is given, it will be converted from a boolean +to a string containing 'true' or 'false'. + +*Examples:* +~~~ +bool2str(true) => 'true' +bool2str(true, 'yes', 'no') => 'yes' +bool2str(false, 't', 'f') => 'f' +~~~ + +Requires a single boolean as input. *Type*: rvalue. + #### `capitalize` Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. @@ -405,7 +459,7 @@ Returns an array an intersection of two. For example, `intersection(["a","b","c" #### `is_a` -Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. +Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. ~~~ foo = 3 @@ -501,6 +555,15 @@ Loads the metadata.json of a target module. Can be used to determine module vers notify { $metadata['author']: } ~~~ +If you do not want to fail the catalog compilation if the metadata file for a module is not present: + + ~~~ + $metadata = load_module_metadata('mysql', true) + if empty($metadata) { + notify { "This module does not have a metadata.json file.": } + } + ~~~ + *Type*: rvalue. #### `lstrip` diff --git a/stdlib/lib/facter/pe_version.rb b/stdlib/lib/facter/pe_version.rb index 0cc0f64e9..c9f2181c0 100644 --- a/stdlib/lib/facter/pe_version.rb +++ b/stdlib/lib/facter/pe_version.rb @@ -10,8 +10,13 @@ # Facter.add("pe_version") do setcode do - pe_ver = Facter.value("puppetversion").match(/Puppet Enterprise (\d+\.\d+\.\d+)/) - pe_ver[1] if pe_ver + puppet_ver = Facter.value("puppetversion") + if puppet_ver != nil + pe_ver = puppet_ver.match(/Puppet Enterprise (\d+\.\d+\.\d+)/) + pe_ver[1] if pe_ver + else + nil + end end end diff --git a/stdlib/lib/puppet/parser/functions/bool2str.rb b/stdlib/lib/puppet/parser/functions/bool2str.rb index fcd379178..7e364747c 100644 --- a/stdlib/lib/puppet/parser/functions/bool2str.rb +++ b/stdlib/lib/puppet/parser/functions/bool2str.rb @@ -4,15 +4,29 @@ module Puppet::Parser::Functions newfunction(:bool2str, :type => :rvalue, :doc => <<-EOS - Converts a boolean to a string. + Converts a boolean to a string using optionally supplied arguments. The + optional second and third arguments represent what true and false will be + converted to respectively. If only one argument is given, it will be + converted from a boolean to a string containing 'true' or 'false'. + + *Examples:* + + bool2str(true) => 'true' + bool2str(true, 'yes', 'no') => 'yes' + bool2str(false, 't', 'f') => 'f' + Requires a single boolean as an input. EOS ) do |arguments| - raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + unless arguments.size == 1 or arguments.size == 3 + raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " + + "given (#{arguments.size} for 3)") + end value = arguments[0] + true_string = arguments[1] || 'true' + false_string = arguments[2] || 'false' klass = value.class # We can have either true or false, and nothing else @@ -20,7 +34,11 @@ module Puppet::Parser::Functions raise(Puppet::ParseError, 'bool2str(): Requires a boolean to work with') end - return value.to_s + unless [true_string, false_string].all?{|x| x.kind_of?(String)} + raise(Puppet::ParseError, "bool2str(): Requires strings to convert to" ) + end + + return value ? true_string : false_string end end diff --git a/stdlib/lib/puppet/parser/functions/load_module_metadata.rb b/stdlib/lib/puppet/parser/functions/load_module_metadata.rb index 0664a2318..c9b84885b 100644 --- a/stdlib/lib/puppet/parser/functions/load_module_metadata.rb +++ b/stdlib/lib/puppet/parser/functions/load_module_metadata.rb @@ -2,14 +2,22 @@ module Puppet::Parser::Functions newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-EOT EOT ) do |args| - raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one") unless args.size == 1 + raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one or two") unless [1,2].include?(args.size) mod = args[0] + allow_empty_metadata = args[1] module_path = function_get_module_path([mod]) metadata_json = File.join(module_path, 'metadata.json') - raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") unless File.exists?(metadata_json) - - metadata = PSON.load(File.read(metadata_json)) + metadata_exists = File.exists?(metadata_json) + if metadata_exists + metadata = PSON.load(File.read(metadata_json)) + else + if allow_empty_metadata + metadata = {} + else + raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") + end + end return metadata end diff --git a/stdlib/lib/puppet/type/file_line.rb b/stdlib/lib/puppet/type/file_line.rb index 446f103eb..77d3be261 100644 --- a/stdlib/lib/puppet/type/file_line.rb +++ b/stdlib/lib/puppet/type/file_line.rb @@ -4,7 +4,7 @@ Ensures that a given line is contained within a file. The implementation matches the full line, including whitespace at the beginning and end. If the line is not contained in the given file, Puppet will append the line to - the end of the file to ensure the desired state. Multiple resources may + the end of the file to ensure the desired state. Multiple resources may be declared to manage multiple lines in the same file. Example: @@ -31,7 +31,7 @@ match => '^export\ HTTP_PROXY\=', } - In this code example match will look for a line beginning with export + In this code example match will look for a line beginning with export followed by HTTP_PROXY and replace it with the value in line. Match Example With `ensure => absent`: @@ -50,7 +50,6 @@ **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. - EOT ensurable do @@ -63,10 +62,10 @@ end newparam(:match) do - desc 'An optional ruby regular expression to run against existing lines in the file.' + + desc 'An optional ruby regular expression to run against existing lines in the file.' + ' If a match is found, we replace that line rather than adding a new line.' + - ' A regex comparisson is performed against the line value and if it does not' + - ' match an exception will be raised. ' + ' A regex comparison is performed against the line value and if it does not' + + ' match an exception will be raised.' end newparam(:match_for_absence) do diff --git a/stdlib/spec/functions/bool2str_spec.rb b/stdlib/spec/functions/bool2str_spec.rb index 8d35598e8..23a754ba4 100755 --- a/stdlib/spec/functions/bool2str_spec.rb +++ b/stdlib/spec/functions/bool2str_spec.rb @@ -6,6 +6,12 @@ [ 'true', 'false', nil, :undef, ''].each do |invalid| it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError) } end + it { is_expected.to run.with_params(true, 'yes', 'no', 'maybe').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(true, 'maybe').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(true, 0, 1).and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(true).and_return("true") } it { is_expected.to run.with_params(false).and_return("false") } + it { is_expected.to run.with_params(true, 'yes', 'no').and_return("yes") } + it { is_expected.to run.with_params(false, 'yes', 'no').and_return("no") } + end diff --git a/stdlib/spec/functions/load_module_metadata.rb b/stdlib/spec/functions/load_module_metadata.rb deleted file mode 100755 index ba542eb7e..000000000 --- a/stdlib/spec/functions/load_module_metadata.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe 'load_module_metadata' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - it "should json parse the file" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) - allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') - - result = subject.call(['science']) - expect(result['name']).to eq('spencer-science') - end -end diff --git a/stdlib/spec/functions/load_module_metadata_spec.rb b/stdlib/spec/functions/load_module_metadata_spec.rb new file mode 100755 index 000000000..fe665fb50 --- /dev/null +++ b/stdlib/spec/functions/load_module_metadata_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe 'load_module_metadata' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it "should json parse the file" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) + allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') + + result = subject.call(['science']) + expect(result['name']).to eq('spencer-science') + end + + it "should fail by default if there is no metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) + expect {subject.call(['science'])}.to raise_error(Puppet::ParseError) + end + + it "should return nil if user allows empty metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) + result = subject.call(['science', true]) + expect(result).to eq({}) + end +end diff --git a/stdlib/spec/unit/facter/pe_version_spec.rb b/stdlib/spec/unit/facter/pe_version_spec.rb index 4d0349e62..c11a1cd09 100755 --- a/stdlib/spec/unit/facter/pe_version_spec.rb +++ b/stdlib/spec/unit/facter/pe_version_spec.rb @@ -14,6 +14,17 @@ Facter.collection.loader.load(:pe_version) end end + + context "When puppetversion is nil" do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(nil) + end + + it "pe_version is nil" do + expect(Facter.fact(:puppetversion).value).to be_nil + expect(Facter.fact(:pe_version).value).to be_nil + end + end context "If PE is installed" do %w{ 2.6.1 2.10.300 }.each do |version| @@ -73,4 +84,5 @@ expect(Facter.fact(:pe_patch_version).value).to be_nil end end + end diff --git a/trove/manifests/api.pp b/trove/manifests/api.pp index d54351bc1..2d5d4dff9 100644 --- a/trove/manifests/api.pp +++ b/trove/manifests/api.pp @@ -327,7 +327,7 @@ 'DEFAULT/heat_service_type': value => $::trove::heat_service_type; } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' or $::trove::rpc_backend == 'rabbit' { if ! $::trove::rabbit_password { fail('When rpc_backend is rabbitmq, you must set rabbit password') } @@ -385,7 +385,7 @@ } } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' or $::trove::rpc_backend == 'qpid'{ trove_config { 'oslo_messaging_qpid/qpid_hostname': value => $::trove::qpid_hostname; 'oslo_messaging_qpid/qpid_port': value => $::trove::qpid_port; diff --git a/trove/manifests/conductor.pp b/trove/manifests/conductor.pp index b2c788d56..7ef7efb33 100644 --- a/trove/manifests/conductor.pp +++ b/trove/manifests/conductor.pp @@ -106,7 +106,7 @@ 'DEFAULT/rpc_backend': value => $::trove::rpc_backend; } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' or $::trove::rpc_backend == 'rabbit' { if ! $::trove::rabbit_password { fail('When rpc_backend is rabbitmq, you must set rabbit password') } @@ -164,7 +164,7 @@ } } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' or $::trove::rpc_backend == 'qpid'{ trove_conductor_config { 'oslo_messaging_qpid/qpid_hostname': value => $::trove::qpid_hostname; 'oslo_messaging_qpid/qpid_port': value => $::trove::qpid_port; diff --git a/trove/manifests/guestagent.pp b/trove/manifests/guestagent.pp index 3feabc13d..ab770d0b0 100644 --- a/trove/manifests/guestagent.pp +++ b/trove/manifests/guestagent.pp @@ -103,7 +103,7 @@ trove_guestagent_config {'DEFAULT/os_region_name': ensure => absent } } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' or $::trove::rpc_backend == 'rabbit' { if ! $::trove::rabbit_password { fail('When rpc_backend is rabbitmq, you must set rabbit password') } @@ -161,7 +161,7 @@ } } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' or $::trove::rpc_backend == 'qpid'{ trove_guestagent_config { 'oslo_messaging_qpid/qpid_hostname': value => $::trove::qpid_hostname; 'oslo_messaging_qpid/qpid_port': value => $::trove::qpid_port; diff --git a/trove/manifests/init.pp b/trove/manifests/init.pp index d31cf1f3b..734d77cea 100644 --- a/trove/manifests/init.pp +++ b/trove/manifests/init.pp @@ -115,9 +115,9 @@ # # [*rpc_backend*] # (optional) The rpc backend implementation to use, can be: -# trove.openstack.common.rpc.impl_kombu (for rabbitmq) -# trove.openstack.common.rpc.impl_qpid (for qpid) -# Defaults to 'trove.openstack.common.rpc.impl_kombu' +# rabbit (for rabbitmq) +# qpid (for qpid) +# Defaults to 'rabbit' # # [*mysql_module*] # (optional) Deprecated. Does nothing. @@ -222,7 +222,7 @@ $qpid_tcp_nodelay = true, $database_connection = 'sqlite:////var/lib/trove/trove.sqlite', $database_idle_timeout = 3600, - $rpc_backend = 'trove.openstack.common.rpc.impl_kombu', + $rpc_backend = 'rabbit', $nova_compute_url = false, $nova_proxy_admin_user = 'admin', $nova_proxy_admin_tenant_name = 'admin', diff --git a/trove/manifests/taskmanager.pp b/trove/manifests/taskmanager.pp index c8873018b..b8af55f31 100644 --- a/trove/manifests/taskmanager.pp +++ b/trove/manifests/taskmanager.pp @@ -156,7 +156,7 @@ 'DEFAULT/heat_service_type': value => $::trove::heat_service_type; } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' or $::trove::rpc_backend == 'rabbit'{ if ! $::trove::rabbit_password { fail('When rpc_backend is rabbitmq, you must set rabbit password') } @@ -214,7 +214,7 @@ } } - if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' or $::trove::rpc_backend == 'qpid'{ trove_taskmanager_config { 'oslo_messaging_qpid/qpid_hostname': value => $::trove::qpid_hostname; 'oslo_messaging_qpid/qpid_port': value => $::trove::qpid_port; diff --git a/trove/spec/classes/trove_api_spec.rb b/trove/spec/classes/trove_api_spec.rb index c8f0972d5..6a3f4db8d 100644 --- a/trove/spec/classes/trove_api_spec.rb +++ b/trove/spec/classes/trove_api_spec.rb @@ -138,13 +138,13 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password'}" end it 'configures trove-api with qpid' do - is_expected.to contain_trove_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_password').with_value('password') @@ -156,14 +156,14 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password', qpid_protocol => 'ssl'}" end it 'configures trove-api with qpid' do - is_expected.to contain_trove_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_config('oslo_messaging_qpid/qpid_password').with_value('password') diff --git a/trove/spec/classes/trove_conductor_spec.rb b/trove/spec/classes/trove_conductor_spec.rb index aeedecb42..183b1e6dd 100644 --- a/trove/spec/classes/trove_conductor_spec.rb +++ b/trove/spec/classes/trove_conductor_spec.rb @@ -59,13 +59,13 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password'}" end it 'configures trove-conductor with qpid' do - is_expected.to contain_trove_conductor_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_conductor_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_password').with_value('password') @@ -77,14 +77,14 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password', qpid_protocol => 'ssl'}" end it 'configures trove-conductor with qpid' do - is_expected.to contain_trove_conductor_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_conductor_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_conductor_config('oslo_messaging_qpid/qpid_password').with_value('password') diff --git a/trove/spec/classes/trove_guestagent_spec.rb b/trove/spec/classes/trove_guestagent_spec.rb index 3c03e89c1..642016d99 100644 --- a/trove/spec/classes/trove_guestagent_spec.rb +++ b/trove/spec/classes/trove_guestagent_spec.rb @@ -61,13 +61,13 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password'}" end it 'configures trove-guestagent with qpid' do - is_expected.to contain_trove_guestagent_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_guestagent_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_password').with_value('password') @@ -79,14 +79,14 @@ let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password', qpid_protocol => 'ssl'}" end it 'configures trove-guestagent with qpid' do - is_expected.to contain_trove_guestagent_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_guestagent_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_guestagent_config('oslo_messaging_qpid/qpid_password').with_value('password') diff --git a/trove/spec/classes/trove_taskmanager_spec.rb b/trove/spec/classes/trove_taskmanager_spec.rb index 7c8c7ac6c..68d250333 100644 --- a/trove/spec/classes/trove_taskmanager_spec.rb +++ b/trove/spec/classes/trove_taskmanager_spec.rb @@ -109,13 +109,13 @@ class { 'trove::taskmanager': let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password'}" end it 'configures trove-taskmanager with qpid' do - is_expected.to contain_trove_taskmanager_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_taskmanager_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_password').with_value('password') @@ -127,14 +127,14 @@ class { 'trove::taskmanager': let :pre_condition do "class { 'trove': nova_proxy_admin_pass => 'verysecrete', - rpc_backend => 'trove.openstack.common.rpc.impl_qpid', + rpc_backend => 'qpid', qpid_hostname => '10.0.0.1', qpid_username => 'guest', qpid_password => 'password', qpid_protocol => 'ssl'}" end it 'configures trove-taskmanager with qpid' do - is_expected.to contain_trove_taskmanager_config('DEFAULT/rpc_backend').with_value('trove.openstack.common.rpc.impl_qpid') + is_expected.to contain_trove_taskmanager_config('DEFAULT/rpc_backend').with_value('qpid') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_hostname').with_value('10.0.0.1') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_username').with_value('guest') is_expected.to contain_trove_taskmanager_config('oslo_messaging_qpid/qpid_password').with_value('password') diff --git a/vcsrepo/Gemfile b/vcsrepo/Gemfile index bfe64b186..ee1eb6b25 100644 --- a/vcsrepo/Gemfile +++ b/vcsrepo/Gemfile @@ -16,6 +16,7 @@ group :development, :unit_tests do gem 'simplecov', :require => false gem 'puppet_facts', :require => false gem 'json', :require => false + gem 'pry', :require => false end group :system_tests do diff --git a/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb b/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb index ba77464a6..fccfaa5a3 100644 --- a/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb +++ b/vcsrepo/lib/puppet/provider/vcsrepo/svn.rb @@ -63,7 +63,7 @@ def buildargs args.push('--config-dir', @resource.value(:configuration)) end - if @resource.value(:trust_server_cert) + if @resource.value(:trust_server_cert) != :false args.push('--trust-server-cert') end diff --git a/vcsrepo/lib/puppet/type/vcsrepo.rb b/vcsrepo/lib/puppet/type/vcsrepo.rb index da1dcde0d..290bdad74 100644 --- a/vcsrepo/lib/puppet/type/vcsrepo.rb +++ b/vcsrepo/lib/puppet/type/vcsrepo.rb @@ -231,7 +231,7 @@ def retrieve newparam :trust_server_cert do desc "Trust server certificate" newvalues(:true, :false) - defaultto false + defaultto :false end autorequire(:package) do diff --git a/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb b/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb index 25951bd88..6a37c205b 100644 --- a/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb +++ b/vcsrepo/spec/unit/puppet/provider/vcsrepo/svn_spec.rb @@ -65,9 +65,17 @@ end context "with trust_server_cert" do + it "should execute 'svn checkout' without a trust-server-cert" do + resource[:source] = 'exists' + resource[:trust_server_cert] = :false + provider.expects(:svn).with('--non-interactive', 'checkout', + resource.value(:source), + resource.value(:path)) + provider.create + end it "should execute 'svn checkout' with a trust-server-cert" do resource[:source] = 'exists' - resource[:trust_server_cert] = true + resource[:trust_server_cert] = :true provider.expects(:svn).with('--non-interactive', '--trust-server-cert', 'checkout', resource.value(:source), resource.value(:path))