From 75e4f4c3c07def4ea51b5e7e4042929f7395ed2f Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Fri, 19 Dec 2014 15:37:45 +0100 Subject: [PATCH 1/6] Update ceilometer to 953ce5032cb332bf8a15e78358ee8af6f14dd7f0 953ce5032cb332bf8a15e78358ee8af6f14dd7f0 crontab: ensure the script is run with shell --- Puppetfile | 2 +- ceilometer/manifests/expirer.pp | 2 +- ceilometer/spec/classes/ceilometer_expirer_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Puppetfile b/Puppetfile index 74c0057f9..17d5b74d0 100644 --- a/Puppetfile +++ b/Puppetfile @@ -7,7 +7,7 @@ mod 'aviator', :git => 'https://github.com/aimonb/puppet_aviator.git' mod 'ceilometer', - :commit => 'ee2f3cd4498b2ef3a6633991206b7185c1d32897', + :commit => '953ce5032cb332bf8a15e78358ee8af6f14dd7f0', :git => 'https://github.com/stackforge/puppet-ceilometer.git' mod 'certmonger', diff --git a/ceilometer/manifests/expirer.pp b/ceilometer/manifests/expirer.pp index 597b09cb4..07a16fb7a 100644 --- a/ceilometer/manifests/expirer.pp +++ b/ceilometer/manifests/expirer.pp @@ -61,7 +61,7 @@ cron { 'ceilometer-expirer': command => $ceilometer::params::expirer_command, - environment => 'PATH=/bin:/usr/bin:/usr/sbin', + environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', user => 'ceilometer', minute => $minute, hour => $hour, diff --git a/ceilometer/spec/classes/ceilometer_expirer_spec.rb b/ceilometer/spec/classes/ceilometer_expirer_spec.rb index 08d62fd38..945c9f122 100644 --- a/ceilometer/spec/classes/ceilometer_expirer_spec.rb +++ b/ceilometer/spec/classes/ceilometer_expirer_spec.rb @@ -44,7 +44,7 @@ it 'configures a cron' do should contain_cron('ceilometer-expirer').with( :command => 'ceilometer-expirer', - :environment => 'PATH=/bin:/usr/bin:/usr/sbin', + :environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', :user => 'ceilometer', :minute => 1, :hour => 0, From aefaabd161e1f0f65bf02ca06b484cf68d30500c Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Fri, 19 Dec 2014 15:38:18 +0100 Subject: [PATCH 2/6] Update keystone to 71a9df884b7a81bf86b6e897c16171bf556f1ea4 71a9df884b7a81bf86b6e897c16171bf556f1ea4 crontab: ensure the script is run with shell --- Puppetfile | 2 +- keystone/manifests/cron/token_flush.pp | 2 +- keystone/spec/classes/keystone_cron_token_flush_spec.rb | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Puppetfile b/Puppetfile index 17d5b74d0..baa350470 100644 --- a/Puppetfile +++ b/Puppetfile @@ -63,7 +63,7 @@ mod 'ipa', :git => 'https://github.com/xbezdick/puppet-ipa.git' mod 'keystone', - :commit => '821cc4ada1f50b5a6c6244cd5c689a467d06d736', + :commit => '71a9df884b7a81bf86b6e897c16171bf556f1ea4', :git => 'https://github.com/stackforge/puppet-keystone.git' mod 'memcached', diff --git a/keystone/manifests/cron/token_flush.pp b/keystone/manifests/cron/token_flush.pp index 177bbe77f..331eeba56 100644 --- a/keystone/manifests/cron/token_flush.pp +++ b/keystone/manifests/cron/token_flush.pp @@ -64,7 +64,7 @@ cron { 'keystone-manage token_flush': ensure => $ensure, command => "${sleep}keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1", - environment => 'PATH=/bin:/usr/bin:/usr/sbin', + environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', user => 'keystone', minute => $minute, hour => $hour, diff --git a/keystone/spec/classes/keystone_cron_token_flush_spec.rb b/keystone/spec/classes/keystone_cron_token_flush_spec.rb index 16f3bbe33..597042b36 100644 --- a/keystone/spec/classes/keystone_cron_token_flush_spec.rb +++ b/keystone/spec/classes/keystone_cron_token_flush_spec.rb @@ -11,7 +11,7 @@ should contain_cron('keystone-manage token_flush').with( :ensure => 'present', :command => 'keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1', - :environment => 'PATH=/bin:/usr/bin:/usr/sbin', + :environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', :user => 'keystone', :minute => 1, :hour => 0, @@ -33,7 +33,7 @@ should contain_cron('keystone-manage token_flush').with( :ensure => 'present', :command => 'sleep `expr ${RANDOM} \\% 600`; keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1', - :environment => 'PATH=/bin:/usr/bin:/usr/sbin', + :environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', :user => 'keystone', :minute => 1, :hour => 0, @@ -55,7 +55,7 @@ should contain_cron('keystone-manage token_flush').with( :ensure => 'absent', :command => 'keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1', - :environment => 'PATH=/bin:/usr/bin:/usr/sbin', + :environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', :user => 'keystone', :minute => 1, :hour => 0, From 94b24e2f49fc8cddc31bcc99ba22b2504a23218b Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Fri, 19 Dec 2014 15:38:30 +0100 Subject: [PATCH 3/6] Update neutron to c3dc52023dfdf7649080c1b5bc5eae3b43991db1 c3dc52023dfdf7649080c1b5bc5eae3b43991db1 Fix l3_ha enablement --- Puppetfile | 2 +- neutron/manifests/server.pp | 2 +- neutron/spec/classes/neutron_server_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Puppetfile b/Puppetfile index baa350470..0fb350560 100644 --- a/Puppetfile +++ b/Puppetfile @@ -91,7 +91,7 @@ mod 'nagios', :git => 'https://github.com/gildub/puppet-nagios-openstack.git' mod 'neutron', - :commit => '67abde86d53969329bce37725627c2c661e49765', + :commit => 'c3dc52023dfdf7649080c1b5bc5eae3b43991db1', :git => 'https://github.com/stackforge/puppet-neutron.git' mod 'nova', diff --git a/neutron/manifests/server.pp b/neutron/manifests/server.pp index 4921fca7e..b5678378e 100644 --- a/neutron/manifests/server.pp +++ b/neutron/manifests/server.pp @@ -232,7 +232,7 @@ if $l3_ha { if $min_l3_agents_per_router <= $max_l3_agents_per_router or $max_l3_agents_per_router == '0' { neutron_config { - 'DEFAULT/ha_enabled': value => true; + 'DEFAULT/l3_ha': value => true; 'DEFAULT/max_l3_agents_per_router': value => $max_l3_agents_per_router; 'DEFAULT/min_l3_agents_per_router': value => $min_l3_agents_per_router; 'DEFAULT/l3_ha_net_cidr': value => $l3_ha_net_cidr; diff --git a/neutron/spec/classes/neutron_server_spec.rb b/neutron/spec/classes/neutron_server_spec.rb index 878bee184..e54bf7c5a 100644 --- a/neutron/spec/classes/neutron_server_spec.rb +++ b/neutron/spec/classes/neutron_server_spec.rb @@ -121,7 +121,7 @@ params.merge!(:l3_ha => true) end it 'should enable HA routers' do - should contain_neutron_config('DEFAULT/ha_enabled').with_value(true) + should contain_neutron_config('DEFAULT/l3_ha').with_value(true) should contain_neutron_config('DEFAULT/max_l3_agents_per_router').with_value('3') should contain_neutron_config('DEFAULT/min_l3_agents_per_router').with_value('2') should contain_neutron_config('DEFAULT/l3_ha_net_cidr').with_value('169.254.192.0/18') From 45f23dcb9c10ce80fb2195f4a34c00bb22dfc7a7 Mon Sep 17 00:00:00 2001 From: Lukas Bezdicka Date: Fri, 19 Dec 2014 15:38:42 +0100 Subject: [PATCH 4/6] Update vswitch to a36332da0ddb9d419e1d3f9d170058284b144f06 a36332da0ddb9d419e1d3f9d170058284b144f06 Merge "Release 1.0.0 - Juno" b3fdd245a59b36fbc943bed481ac26c6f987845a Release 1.0.0 - Juno fab186f37b8729401913f765ce22d401a2ef3485 Fixed issue with vlan on redhat provider --- Puppetfile | 2 +- vswitch/README.md | 6 +++++- vswitch/lib/puppet/provider/vs_port/ovs_redhat.rb | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Puppetfile b/Puppetfile index 0fb350560..d6fbfc491 100644 --- a/Puppetfile +++ b/Puppetfile @@ -175,7 +175,7 @@ mod 'vlan', :git => 'https://github.com/derekhiggins/puppet-vlan.git' mod 'vswitch', - :commit => '51fd30c22b79d927fb0329e6e2b58fe67217ecee', + :commit => 'a36332da0ddb9d419e1d3f9d170058284b144f06', :git => 'https://github.com/stackforge/puppet-vswitch.git' mod 'xinetd', diff --git a/vswitch/README.md b/vswitch/README.md index c5f67fb41..8c2a87bfb 100644 --- a/vswitch/README.md +++ b/vswitch/README.md @@ -1,4 +1,8 @@ -# puppet-vswitch +VSwitch +======= + +1.0.0 - 2014.2.0 - Juno + A Puppet module providing things for vSwitches. At the moment OVS is the only one I've added but please feel free to contribute new providers through Stackforge. It's based upon types and providers so we can support more then just diff --git a/vswitch/lib/puppet/provider/vs_port/ovs_redhat.rb b/vswitch/lib/puppet/provider/vs_port/ovs_redhat.rb index f2cf88dbd..2bc4374aa 100644 --- a/vswitch/lib/puppet/provider/vs_port/ovs_redhat.rb +++ b/vswitch/lib/puppet/provider/vs_port/ovs_redhat.rb @@ -39,6 +39,9 @@ def create end port = IFCFG::Port.new(@resource[:interface], @resource[:bridge]) + if vlan? + port.set('VLAN' => 'yes') + end port.save(BASE + @resource[:interface]) bridge = IFCFG::Bridge.new(@resource[:bridge], template) @@ -115,6 +118,17 @@ def from_str(data) items.merge!(m[1] => m[2]) end end + items.delete('VLAN') if items.has_key?('VLAN') items end + + def vlan? + if File.read('/proc/net/vlan/config') =~ /#{@resource[:interface]}/ + return true + else + return false + end + rescue Errno::ENOENT + return false + end end From 33cefd408893810f1053a0c352c330705cff02a0 Mon Sep 17 00:00:00 2001 From: Ivan Chavero Date: Thu, 18 Dec 2014 09:33:02 -0700 Subject: [PATCH 5/6] Automatic update This module update commit was generated by Bade. For more info please check https://github.com/paramite/bade This commit is setting modules to following state: trove - initial commit: 2ef93e8e90978915d166ed21fd53dab67f820fe7 --- Puppetfile | 4 + trove/.fixtures.yml | 14 + trove/.gitignore | 7 + trove/.gitreview | 4 + trove/Gemfile | 18 + trove/LICENSE | 176 +++++++++ trove/README.md | 54 +++ trove/Rakefile | 9 + trove/examples/site.pp | 38 ++ trove/lib/puppet/provider/trove.rb | 113 ++++++ .../trove_api_paste_ini/ini_setting.rb | 27 ++ .../trove_conductor_config/ini_setting.rb | 27 ++ .../provider/trove_config/ini_setting.rb | 27 ++ .../puppet/provider/trove_datastore/trove.rb | 52 +++ .../provider/trove_datastore_version/trove.rb | 60 +++ .../trove_guestagent_config/ini_setting.rb | 27 ++ .../trove_taskmanager_config/ini_setting.rb | 27 ++ trove/lib/puppet/type/trove_api_paste_ini.rb | 42 +++ .../lib/puppet/type/trove_conductor_config.rb | 42 +++ trove/lib/puppet/type/trove_config.rb | 42 +++ trove/lib/puppet/type/trove_datastore.rb | 26 ++ .../puppet/type/trove_datastore_version.rb | 38 ++ .../puppet/type/trove_guestagent_config.rb | 42 +++ .../puppet/type/trove_taskmanager_config.rb | 42 +++ trove/manifests/api.pp | 341 ++++++++++++++++++ trove/manifests/client.pp | 40 ++ trove/manifests/conductor.pp | 196 ++++++++++ trove/manifests/db/mysql.pp | 83 +++++ trove/manifests/db/postgresql.pp | 36 ++ trove/manifests/db/sync.pp | 27 ++ trove/manifests/generic_service.pp | 71 ++++ trove/manifests/guestagent.pp | 190 ++++++++++ trove/manifests/init.pp | 203 +++++++++++ trove/manifests/keystone/auth.pp | 112 ++++++ trove/manifests/params.pp | 33 ++ trove/manifests/taskmanager.pp | 224 ++++++++++++ trove/metadata.json | 39 ++ trove/spec/classes/trove_api_spec.rb | 140 +++++++ trove/spec/classes/trove_client_spec.rb | 55 +++ trove/spec/classes/trove_conductor_spec.rb | 99 +++++ trove/spec/classes/trove_db_mysql_spec.rb | 109 ++++++ .../spec/classes/trove_db_postgresql_spec.rb | 26 ++ trove/spec/classes/trove_guestagent_spec.rb | 105 ++++++ trove/spec/classes/trove_init_spec.rb | 56 +++ .../spec/classes/trove_keystone_auth_spec.rb | 101 ++++++ trove/spec/classes/trove_taskmanager_spec.rb | 118 ++++++ trove/spec/shared_examples.rb | 56 +++ trove/spec/spec_helper.rb | 7 + .../provider/trove_config/ini_setting_spec.rb | 37 ++ .../provider/trove_datastore/trove_spec.rb | 57 +++ .../trove_datastore_version/trove_spec.rb | 50 +++ trove/spec/unit/provider/trove_spec.rb | 14 + trove/spec/unit/type/trove_config_spec.rb | 52 +++ trove/templates/trove-guestagent.conf.erb | 73 ++++ 54 files changed, 3708 insertions(+) create mode 100644 trove/.fixtures.yml create mode 100644 trove/.gitignore create mode 100644 trove/.gitreview create mode 100644 trove/Gemfile create mode 100644 trove/LICENSE create mode 100644 trove/README.md create mode 100644 trove/Rakefile create mode 100644 trove/examples/site.pp create mode 100644 trove/lib/puppet/provider/trove.rb create mode 100644 trove/lib/puppet/provider/trove_api_paste_ini/ini_setting.rb create mode 100644 trove/lib/puppet/provider/trove_conductor_config/ini_setting.rb create mode 100644 trove/lib/puppet/provider/trove_config/ini_setting.rb create mode 100644 trove/lib/puppet/provider/trove_datastore/trove.rb create mode 100644 trove/lib/puppet/provider/trove_datastore_version/trove.rb create mode 100644 trove/lib/puppet/provider/trove_guestagent_config/ini_setting.rb create mode 100644 trove/lib/puppet/provider/trove_taskmanager_config/ini_setting.rb create mode 100644 trove/lib/puppet/type/trove_api_paste_ini.rb create mode 100644 trove/lib/puppet/type/trove_conductor_config.rb create mode 100644 trove/lib/puppet/type/trove_config.rb create mode 100644 trove/lib/puppet/type/trove_datastore.rb create mode 100644 trove/lib/puppet/type/trove_datastore_version.rb create mode 100644 trove/lib/puppet/type/trove_guestagent_config.rb create mode 100644 trove/lib/puppet/type/trove_taskmanager_config.rb create mode 100644 trove/manifests/api.pp create mode 100644 trove/manifests/client.pp create mode 100644 trove/manifests/conductor.pp create mode 100644 trove/manifests/db/mysql.pp create mode 100644 trove/manifests/db/postgresql.pp create mode 100644 trove/manifests/db/sync.pp create mode 100644 trove/manifests/generic_service.pp create mode 100644 trove/manifests/guestagent.pp create mode 100644 trove/manifests/init.pp create mode 100644 trove/manifests/keystone/auth.pp create mode 100644 trove/manifests/params.pp create mode 100644 trove/manifests/taskmanager.pp create mode 100644 trove/metadata.json create mode 100644 trove/spec/classes/trove_api_spec.rb create mode 100644 trove/spec/classes/trove_client_spec.rb create mode 100644 trove/spec/classes/trove_conductor_spec.rb create mode 100644 trove/spec/classes/trove_db_mysql_spec.rb create mode 100644 trove/spec/classes/trove_db_postgresql_spec.rb create mode 100644 trove/spec/classes/trove_guestagent_spec.rb create mode 100644 trove/spec/classes/trove_init_spec.rb create mode 100644 trove/spec/classes/trove_keystone_auth_spec.rb create mode 100644 trove/spec/classes/trove_taskmanager_spec.rb create mode 100644 trove/spec/shared_examples.rb create mode 100644 trove/spec/spec_helper.rb create mode 100644 trove/spec/unit/provider/trove_config/ini_setting_spec.rb create mode 100644 trove/spec/unit/provider/trove_datastore/trove_spec.rb create mode 100644 trove/spec/unit/provider/trove_datastore_version/trove_spec.rb create mode 100644 trove/spec/unit/provider/trove_spec.rb create mode 100644 trove/spec/unit/type/trove_config_spec.rb create mode 100644 trove/templates/trove-guestagent.conf.erb diff --git a/Puppetfile b/Puppetfile index d6fbfc491..d8870a394 100644 --- a/Puppetfile +++ b/Puppetfile @@ -166,6 +166,10 @@ mod 'tempest', :commit => '7a3369949fc8af41e190dd8115391354a7575ecb', :git => 'https://github.com/stackforge/puppet-tempest.git' +mod 'trove', + :commit => '2ef93e8e90978915d166ed21fd53dab67f820fe7', + :git => 'https://github.com/stackforge/puppet-trove' + mod 'vcsrepo', :commit => '6f7507a2a48ff0a58c7db026760a2eb84e382a77', :git => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git' diff --git a/trove/.fixtures.yml b/trove/.fixtures.yml new file mode 100644 index 000000000..6f8234f36 --- /dev/null +++ b/trove/.fixtures.yml @@ -0,0 +1,14 @@ +fixtures: + repositories: + 'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile' + 'keystone': 'git://github.com/stackforge/puppet-keystone.git' + 'mysql': + repo: 'git://github.com/puppetlabs/puppetlabs-mysql.git' + ref: 'origin/2.2.x' + 'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git' + 'postgresql': + repo: 'git://github.com/puppetlabs/puppet-postgresql.git' + ref: '2.5.0' + 'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git' + symlinks: + 'trove': "#{source_dir}" diff --git a/trove/.gitignore b/trove/.gitignore new file mode 100644 index 000000000..da4238187 --- /dev/null +++ b/trove/.gitignore @@ -0,0 +1,7 @@ +*.swp +spec/fixtures/modules/* +spec/fixtures/manifests/site.pp +Gemfile.lock +.vendor +.bundle/ +vendor/ diff --git a/trove/.gitreview b/trove/.gitreview new file mode 100644 index 000000000..b34cb118f --- /dev/null +++ b/trove/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=review.openstack.org +port=29418 +project=stackforge/puppet-trove.git diff --git a/trove/Gemfile b/trove/Gemfile new file mode 100644 index 000000000..d965fa900 --- /dev/null +++ b/trove/Gemfile @@ -0,0 +1,18 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'puppetlabs_spec_helper', :require => false + gem 'puppet-lint', '~> 0.3.2' + gem 'rake', '10.1.1' + gem 'rspec', '< 2.99' + gem 'json' + gem 'webmock' +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +# vim:ft=ruby diff --git a/trove/LICENSE b/trove/LICENSE new file mode 100644 index 000000000..68c771a09 --- /dev/null +++ b/trove/LICENSE @@ -0,0 +1,176 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + diff --git a/trove/README.md b/trove/README.md new file mode 100644 index 000000000..a155caf00 --- /dev/null +++ b/trove/README.md @@ -0,0 +1,54 @@ +puppet-trove +============= + +#### Table of Contents + +1. [Overview - What is the trove module?](#overview) +2. [Module Description - What does the module do?](#module-description) +3. [Setup - The basics of getting started with trove](#setup) +4. [Implementation - An under-the-hood peek at what the module is doing](#implementation) +5. [Limitations - OS compatibility, etc.](#limitations) +6. [Development - Guide for contributing to the module](#development) +7. [Contributors - Those with commits](#contributors) +8. [Release Notes - Notes on the most recent updates to the module](#release-notes) + +Overview +-------- + +The trove module is a part of [Stackforge](https://github.com/stackforge), an effort by the Openstack infrastructure team to provide continuous integration testing and code review for Openstack and Openstack community projects not part of the core software. The module itself is used to flexibly configure and manage the database service for Openstack. + +Module Description +------------------ + +Setup +----- + +**What the trove module affects:** + +* trove, the database service for Openstack. + +Implementation +-------------- + +### trove + +trove is a combination of Puppet manifest and ruby code to delivery configuration and extra functionality through types and providers. + +Limitations +----------- + +Development +----------- + +Developer documentation for the entire puppet-openstack project. + +* https://wiki.openstack.org/wiki/Puppet-openstack#Developer_documentation + +Contributors +------------ + +* https://github.com/enovance/puppet-trove/graphs/contributors + +Release Notes +------------- + diff --git a/trove/Rakefile b/trove/Rakefile new file mode 100644 index 000000000..84c9a7046 --- /dev/null +++ b/trove/Rakefile @@ -0,0 +1,9 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_parameter_defaults') + +task(:default).clear +task :default => [:spec, :lint] diff --git a/trove/examples/site.pp b/trove/examples/site.pp new file mode 100644 index 000000000..b9ecee526 --- /dev/null +++ b/trove/examples/site.pp @@ -0,0 +1,38 @@ +# This is an example of site.pp to deploy Trove + +class { 'trove::client': } + +class { 'trove::keystone::auth': + admin_address => '10.0.0.1', + internal_address => '10.0.0.1', + public_address => '10.0.0.1', + password => 'verysecrete', + region => 'OpenStack' +} + +class { 'trove::db::mysql': + password => 'dbpass', + host => '10.0.0.1', + allowed_hosts => '10.0.0.1' +} + +class { 'trove': + database_connection => 'mysql://trove:secrete@10.0.0.1/trove?charset=utf8', + rabbit_hosts => '10.0.0.1', + rabbit_password => 'secrete', + nova_proxy_admin_pass => 'novapass', +} + +class { 'trove::api': + bind_host => '10.0.0.1', + auth_url => 'https://identity.openstack.org:5000/v2.0', + keystone_password => 'verysecrete' +} + +class { 'trove::conductor': + auth_url => 'https://identity.openstack.org:5000/v2.0' +} + +class { 'trove::taskmanager': + auth_url => 'https://identity.openstack.org:5000/v2.0' +} diff --git a/trove/lib/puppet/provider/trove.rb b/trove/lib/puppet/provider/trove.rb new file mode 100644 index 000000000..4a53bbadf --- /dev/null +++ b/trove/lib/puppet/provider/trove.rb @@ -0,0 +1,113 @@ +require 'json' +require 'puppet/util/inifile' + +class Puppet::Provider::Trove < Puppet::Provider + + def self.conf_filename + '/etc/trove/trove.conf' + end + + def self.withenv(hash, &block) + saved = ENV.to_hash + hash.each do |name, val| + ENV[name.to_s] = val + end + + yield + ensure + ENV.clear + saved.each do |name, val| + ENV[name] = val + end + end + + def self.trove_credentials + @trove_credentials ||= get_trove_credentials + end + + def self.get_trove_credentials + auth_keys = ['auth_host', 'auth_port', 'auth_protocol', + 'admin_tenant_name', 'admin_user', 'admin_password'] + conf = trove_conf + if conf and conf['keystone_authtoken'] and + auth_keys.all?{|k| !conf['keystone_authtoken'][k].nil?} + return Hash[ auth_keys.map \ + { |k| [k, conf['keystone_authtoken'][k].strip] } ] + else + raise(Puppet::Error, "File: #{conf_filename} does not contain all \ +required sections. Trove types will not work if trove is not \ +correctly configured.") + end + end + + def trove_credentials + self.class.trove_credentials + end + + def self.auth_endpoint + @auth_endpoint ||= get_auth_endpoint + end + + def self.get_auth_endpoint + q = trove_credentials + "#{q['auth_protocol']}://#{q['auth_host']}:#{q['auth_port']}/v2.0/" + end + + def self.trove_conf + return @trove_conf if @trove_conf + @trove_conf = Puppet::Util::IniConfig::File.new + @trove_conf.read(conf_filename) + @trove_conf + end + + def self.auth_trove(*args) + q = trove_credentials + authenv = { + :OS_AUTH_URL => self.auth_endpoint, + :OS_USERNAME => q['admin_user'], + :OS_TENANT_NAME => q['admin_tenant_name'], + :OS_PASSWORD => q['admin_password'] + } + begin + withenv authenv do + trove(args) + end + rescue Exception => e + if (e.message =~ /\[Errno 111\] Connection refused/) or + (e.message =~ /\(HTTP 400\)/) + sleep 10 + withenv authenv do + trove(args) + end + else + raise(e) + end + end + end + + def auth_trove(*args) + self.class.auth_trove(args) + end + + def trove_manage(*args) + cmd = args.join(" ") + output = `#{cmd}` + $?.exitstatus + end + + def self.reset + @trove_conf = nil + @trove_credentials = nil + end + + def self.list_trove_resources(type, *args) + json = auth_trove("--json", "#{type}-list", *args) + return JSON.parse(json) + end + + def self.get_trove_resource_attrs(type, id) + json = auth_trove("--json", "#{type}-show", id) + return JSON.parse(json) + end + +end diff --git a/trove/lib/puppet/provider/trove_api_paste_ini/ini_setting.rb b/trove/lib/puppet/provider/trove_api_paste_ini/ini_setting.rb new file mode 100644 index 000000000..e63fd1ee4 --- /dev/null +++ b/trove/lib/puppet/provider/trove_api_paste_ini/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:trove_api_paste_ini).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/trove/api-paste.ini' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/trove/lib/puppet/provider/trove_conductor_config/ini_setting.rb b/trove/lib/puppet/provider/trove_conductor_config/ini_setting.rb new file mode 100644 index 000000000..a4a0f8869 --- /dev/null +++ b/trove/lib/puppet/provider/trove_conductor_config/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:trove_conductor_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/trove/trove-conductor.conf' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/trove/lib/puppet/provider/trove_config/ini_setting.rb b/trove/lib/puppet/provider/trove_config/ini_setting.rb new file mode 100644 index 000000000..d71365c93 --- /dev/null +++ b/trove/lib/puppet/provider/trove_config/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:trove_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/trove/trove.conf' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/trove/lib/puppet/provider/trove_datastore/trove.rb b/trove/lib/puppet/provider/trove_datastore/trove.rb new file mode 100644 index 000000000..d356637e8 --- /dev/null +++ b/trove/lib/puppet/provider/trove_datastore/trove.rb @@ -0,0 +1,52 @@ +require File.join(File.dirname(__FILE__), "..","..","..", + "puppet/provider/trove") + +Puppet::Type.type(:trove_datastore).provide( + :trove, + :parent => Puppet::Provider::Trove +) do + desc <<-EOT + Trove provider to manage datastore type. + EOT + + commands :trove => "trove" + + mk_resource_methods + + def self.instances + list_trove_resources("datastore").collect do |attrs| + new( + :ensure => :present, + :name => attrs["name"], + :id => attrs["id"] + ) + end + end + + def self.prefetch(resources) + instances_ = instances + resources.keys.each do |name| + if provider = instances_.find{ |instance| instance.name == name } + resources[name].provider = provider + end + end + end + + def exists? + @property_hash[:ensure] == :present + end + + def create + if trove_manage(['trove-manage', 'datastore_update', + "#{@resource[:name]}", "''"]) != 0 + fail("Failed to create datastore #{@resource[:name]}") + end + + if trove_manage(['trove-manage', 'datastore_update', + "#{@resource[:name]}", "#{@resource[:version]}"]) != 0 + fail("Failed to set version for datastore #{@resource[:name]}") + end + end + +end + diff --git a/trove/lib/puppet/provider/trove_datastore_version/trove.rb b/trove/lib/puppet/provider/trove_datastore_version/trove.rb new file mode 100644 index 000000000..f02ba2360 --- /dev/null +++ b/trove/lib/puppet/provider/trove_datastore_version/trove.rb @@ -0,0 +1,60 @@ +require File.join(File.dirname(__FILE__), "..","..","..", + "puppet/provider/trove") + +Puppet::Type.type(:trove_datastore_version).provide( + :trove, + :parent => Puppet::Provider::Trove +) do + desc <<-EOT + Trove provider to manage datastore version type. + EOT + + commands :trove => "trove" + + mk_resource_methods + + def self.prefetch(resource) + @datastore_version_hash = nil + end + + def self.datastore_version_hash(datastore) + @datastore_version_hash ||= build_datastore_version_hash(datastore) + end + + def datastore_version_hash(datastore) + self.class.datastore_version_hash(datastore) + end + + def self.instances + [] + end + + def exists? + datastore_version_hash(resource[:datastore])[resource[:name]] + end + + def create + cmd = ['trove-manage', 'datastore_version_update', + "#{@resource[:datastore]}", "#{@resource[:name]}", + "#{@resource[:manager]}", "#{@resource[:image_id]}", + "#{@resource[:packages]}", "#{@resource[:active]}"] + if trove_manage(cmd) != 0 + fail("Failed to create datastore version #{@resource[:name]}") + end + end + + def destroy + fail("Datastore version cannot be removed") + end + + private + + def self.build_datastore_version_hash(datastore) + dvs = {} + list_trove_resources("datastore-version", datastore).collect do |attrs| + dvs[attrs["name"]] = attrs + end + dvs + end + +end diff --git a/trove/lib/puppet/provider/trove_guestagent_config/ini_setting.rb b/trove/lib/puppet/provider/trove_guestagent_config/ini_setting.rb new file mode 100644 index 000000000..d527f3e11 --- /dev/null +++ b/trove/lib/puppet/provider/trove_guestagent_config/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:trove_guestagent_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/trove/trove-guestagent.conf' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/trove/lib/puppet/provider/trove_taskmanager_config/ini_setting.rb b/trove/lib/puppet/provider/trove_taskmanager_config/ini_setting.rb new file mode 100644 index 000000000..5aa953966 --- /dev/null +++ b/trove/lib/puppet/provider/trove_taskmanager_config/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:trove_taskmanager_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/trove/trove-taskmanager.conf' + end + + # added for backwards compatibility with older versions of inifile + def file_path + self.class.file_path + end + +end diff --git a/trove/lib/puppet/type/trove_api_paste_ini.rb b/trove/lib/puppet/type/trove_api_paste_ini.rb new file mode 100644 index 000000000..1ff1a5b56 --- /dev/null +++ b/trove/lib/puppet/type/trove_api_paste_ini.rb @@ -0,0 +1,42 @@ +Puppet::Type.newtype(:trove_api_paste_ini) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/trove/api-paste.ini' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end diff --git a/trove/lib/puppet/type/trove_conductor_config.rb b/trove/lib/puppet/type/trove_conductor_config.rb new file mode 100644 index 000000000..6450a4766 --- /dev/null +++ b/trove/lib/puppet/type/trove_conductor_config.rb @@ -0,0 +1,42 @@ +Puppet::Type.newtype(:trove_conductor_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/trove/trove-conductor.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end diff --git a/trove/lib/puppet/type/trove_config.rb b/trove/lib/puppet/type/trove_config.rb new file mode 100644 index 000000000..f1d14d213 --- /dev/null +++ b/trove/lib/puppet/type/trove_config.rb @@ -0,0 +1,42 @@ +Puppet::Type.newtype(:trove_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/trove/trove.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end diff --git a/trove/lib/puppet/type/trove_datastore.rb b/trove/lib/puppet/type/trove_datastore.rb new file mode 100644 index 000000000..7aa948322 --- /dev/null +++ b/trove/lib/puppet/type/trove_datastore.rb @@ -0,0 +1,26 @@ +Puppet::Type.newtype(:trove_datastore) do + + @doc = "Manage creation of Trove datastores" + + ensurable + + newparam(:name, :namevar => true) do + desc "Datastore version name)" + newvalues(/^.*$/) + end + + newparam(:version) do + desc "Datastore version name" + end + + newproperty(:id) do + validate do |v| + raise(Puppet::Error, 'This is a read only property') + end + end + + validate do + raise(Puppet::Error, 'Version must be set') unless self[:version] + end +end + diff --git a/trove/lib/puppet/type/trove_datastore_version.rb b/trove/lib/puppet/type/trove_datastore_version.rb new file mode 100644 index 000000000..856e06d14 --- /dev/null +++ b/trove/lib/puppet/type/trove_datastore_version.rb @@ -0,0 +1,38 @@ +Puppet::Type.newtype(:trove_datastore_version) do + + @doc = "Manage creation of Trove datastore versions" + + ensurable + + newparam(:name, :namevar => true) do + desc "Datastore version" + end + + newparam(:datastore) do + desc "Datastore name)" + end + + newparam(:manager) do + desc "Manager name" + end + + newparam(:image_id) do + desc "Glance image id" + end + + newparam(:packages) do + desc "Packages to install" + end + + newparam(:active) do + desc "State" + end + + validate do + raise(Puppet::Error, 'Datastore must be set') unless self[:datastore] + raise(Puppet::Error, 'Manager must be set') unless self[:manager] + raise(Puppet::Error, 'Image must be set') unless self[:image_id] + raise(Puppet::Error, 'Packages must be set') unless self[:packages] + raise(Puppet::Error, 'State must be set') unless self[:active] + end +end diff --git a/trove/lib/puppet/type/trove_guestagent_config.rb b/trove/lib/puppet/type/trove_guestagent_config.rb new file mode 100644 index 000000000..06072f8c5 --- /dev/null +++ b/trove/lib/puppet/type/trove_guestagent_config.rb @@ -0,0 +1,42 @@ +Puppet::Type.newtype(:trove_guestagent_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/trove/trove-guestagent.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end diff --git a/trove/lib/puppet/type/trove_taskmanager_config.rb b/trove/lib/puppet/type/trove_taskmanager_config.rb new file mode 100644 index 000000000..25af37653 --- /dev/null +++ b/trove/lib/puppet/type/trove_taskmanager_config.rb @@ -0,0 +1,42 @@ +Puppet::Type.newtype(:trove_taskmanager_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/trove/trove-taskmanager.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end diff --git a/trove/manifests/api.pp b/trove/manifests/api.pp new file mode 100644 index 000000000..ce54bd1cb --- /dev/null +++ b/trove/manifests/api.pp @@ -0,0 +1,341 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class trove::api +# +# Configure API service in trove +# +# == Parameters +# +# [*manage_service*] +# (optional) Whether to start/stop the service +# Defaults to true +# +# [*ensure_package*] +# (optional) Whether the trove api package will be installed +# Defaults to 'present' +# +# [*keystone_password*] +# (required) Password used to authentication. +# +# [*verbose*] +# (optional) Rather to log the trove api service at verbose level. +# Default: false +# +# [*debug*] +# (optional) Rather to log the trove api service at debug level. +# Default: false +# +# [*bind_host*] +# (optional) The address of the host to bind to. +# Default: 0.0.0.0 +# +# [*bind_port*] +# (optional) The port the server should bind to. +# Default: 8779 +# +# [*backlog*] +# (optional) Backlog requests when creating socket +# Default: 4096 +# +# [*workers*] +# (optional) Number of trove API worker processes to start +# Default: $::processorcount +# +# [*log_file*] +# (optional) The path of file used for logging +# If set to boolean false, it will not log to any file. +# Default: /var/log/trove/trove-api.log +# +# [*log_dir*] +# (optional) directory to which trove logs are sent. +# If set to boolean false, it will not log to any directory. +# Defaults to '/var/log/trove' +# +# [* auth_host*] +# (optional) Host running auth service. +# Defaults to '127.0.0.1'. +# +# [*auth_url*] +# (optional) Authentication URL. +# Defaults to 'http://localhost:5000/v2.0'. +# +# [* auth_port*] +# (optional) Port to use for auth service on auth_host. +# Defaults to '35357'. +# +# [* auth_protocol*] +# (optional) Protocol to use for auth. +# Defaults to 'http'. +# +# [*keystone_tenant*] +# (optional) Tenant to authenticate to. +# Defaults to services. +# +# [*keystone_user*] +# (optional) User to authenticate as with keystone. +# Defaults to 'trove'. +# +# [*enabled*] +# (optional) Whether to enable services. +# Defaults to true. +# +# [*use_syslog*] +# (optional) Use syslog for logging. +# Defaults to false. +# +# [*log_facility*] +# (optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER'. +# +# [*purge_config*] +# (optional) Whether to set only the specified config options +# in the api config. +# Defaults to false. +# +# [*cert_file*] +# (optinal) Certificate file to use when starting API server securely +# Defaults to false, not set +# +# [*key_file*] +# (optional) Private key file to use when starting API server securely +# Defaults to false, not set +# +# [*ca_file*] +# (optional) CA certificate file to use to verify connecting clients +# Defaults to false, not set +# +class trove::api( + $keystone_password, + $verbose = false, + $debug = false, + $bind_host = '0.0.0.0', + $bind_port = '8779', + $backlog = '4096', + $workers = $::processorcount, + $log_file = '/var/log/trove/trove-api.log', + $log_dir = '/var/log/trove', + $auth_host = '127.0.0.1', + $auth_url = false, + $auth_port = '35357', + $auth_protocol = 'http', + $keystone_tenant = 'services', + $keystone_user = 'trove', + $enabled = true, + $use_syslog = false, + $log_facility = 'LOG_USER', + $purge_config = false, + $cert_file = false, + $key_file = false, + $ca_file = false, + $manage_service = true, + $ensure_package = 'present', +) inherits trove { + + require keystone::python + include trove::params + + Trove_config<||> ~> Exec['post-trove_config'] + Trove_config<||> ~> Service['trove-api'] + Package['trove-api'] -> Trove_config<||> + Package['trove-api'] -> Trove_api_paste_ini<||> + Trove_api_paste_ini<||> ~> Service['trove-api'] + + if $::trove::database_connection { + if($::trove::database_connection =~ /mysql:\/\/\S+:\S+@\S+\/\S+/) { + require 'mysql::bindings' + require 'mysql::bindings::python' + } elsif($::trove::database_connection =~ /postgresql:\/\/\S+:\S+@\S+\/\S+/) { + + } elsif($::trove::database_connection =~ /sqlite:\/\//) { + + } else { + fail("Invalid db connection ${::trove::database_connection}") + } + trove_config { + 'DEFAULT/sql_connection': value => $::trove::database_connection; + 'DEFAULT/sql_idle_timeout': value => $::trove::database_idle_timeoutl; + } + } + + # basic service config + trove_config { + 'DEFAULT/verbose': value => $verbose; + 'DEFAULT/debug': value => $debug; + 'DEFAULT/bind_host': value => $bind_host; + 'DEFAULT/bind_port': value => $bind_port; + 'DEFAULT/backlog': value => $backlog; + 'DEFAULT/trove_api_workers': value => $workers; + 'DEFAULT/nova_proxy_admin_user': value => $::trove::nova_proxy_admin_user; + 'DEFAULT/nova_proxy_admin_pass': value => $::trove::nova_proxy_admin_pass; + 'DEFAULT/nova_proxy_admin_tenant_name': value => $::trove::nova_proxy_admin_tenant_name; + } + + if $auth_url { + trove_config { 'DEFAULT/trove_auth_url': value => $auth_url; } + } else { + trove_config { 'DEFAULT/trove_auth_url': value => "${auth_protocol}://${auth_host}:5000/v2.0"; } + } + + # auth config + trove_api_paste_ini { + 'filter:authtoken/auth_host': value => $auth_host; + 'filter:authtoken/auth_port': value => $auth_port; + 'filter:authtoken/auth_protocol': value => $auth_protocol; + 'filter:authtoken/admin_tenant_name': value => $keystone_tenant; + 'filter:authtoken/admin_user' : value => $keystone_user; + 'filter:authtoken/admin_password' : value => $keystone_password; + } + + # SSL Options + if $cert_file { + trove_config { + 'DEFAULT/cert_file' : value => $cert_file; + } + } else { + trove_config { + 'DEFAULT/cert_file': ensure => absent; + } + } + if $key_file { + trove_config { + 'DEFAULT/key_file' : value => $key_file; + } + } else { + trove_config { + 'DEFAULT/key_file': ensure => absent; + } + } + if $ca_file { + trove_config { + 'DEFAULT/ca_file' : value => $ca_file; + } + } else { + trove_config { + 'DEFAULT/ca_file': ensure => absent; + } + } + + # Logging + if $log_file { + trove_config { + 'DEFAULT/log_file': value => $log_file; + } + } else { + trove_config { + 'DEFAULT/log_file': ensure => absent; + } + } + + if $log_dir { + trove_config { + 'DEFAULT/log_dir': value => $log_dir; + } + } else { + trove_config { + 'DEFAULT/log_dir': ensure => absent; + } + } + + # Syslog + if $use_syslog { + trove_config { + 'DEFAULT/use_syslog' : value => true; + 'DEFAULT/syslog_log_facility' : value => $log_facility; + } + } else { + trove_config { + 'DEFAULT/use_syslog': value => false; + } + } + + resources { 'trove_config': + purge => $purge_config, + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + # I may want to support exporting and collecting these + trove_config { + 'DEFAULT/rabbit_password': value => $::trove::rabbit_password, secret => true; + 'DEFAULT/rabbit_userid': value => $::trove::rabbit_userid; + 'DEFAULT/rabbit_virtual_host': value => $::trove::rabbit_virtual_host; + 'DEFAULT/rabbit_use_ssl': value => $::trove::rabbit_use_ssl; + 'DEFAULT/amqp_durable_queues': value => $::trove::amqp_durable_queues; + } + + if $::trove::rabbit_use_ssl { + trove_config { + 'DEFAULT/kombu_ssl_ca_certs': value => $::trove::kombu_ssl_ca_certs; + 'DEFAULT/kombu_ssl_certfile': value => $::trove::kombu_ssl_certfile; + 'DEFAULT/kombu_ssl_keyfile': value => $::trove::kombu_ssl_keyfile; + 'DEFAULT/kombu_ssl_version': value => $::trove::kombu_ssl_version; + } + } else { + trove_config { + 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'DEFAULT/kombu_ssl_version': ensure => absent; + } + } + + if $::trove::rabbit_hosts { + trove_config { 'DEFAULT/rabbit_hosts': value => join($::trove::rabbit_hosts, ',') } + trove_config { 'DEFAULT/rabbit_ha_queues': value => true } + } else { + trove_config { 'DEFAULT/rabbit_host': value => $::trove::rabbit_host } + trove_config { 'DEFAULT/rabbit_port': value => $::trove::rabbit_port } + trove_config { 'DEFAULT/rabbit_hosts': value => "${::trove::rabbit_host}:${::trove::rabbit_port}" } + trove_config { 'DEFAULT/rabbit_ha_queues': value => false } + } + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + trove_config { + 'DEFAULT/qpid_hostname': value => $::trove::qpid_hostname; + 'DEFAULT/qpid_port': value => $::trove::qpid_port; + 'DEFAULT/qpid_username': value => $::trove::qpid_username; + 'DEFAULT/qpid_password': value => $::trove::qpid_password, secret => true; + 'DEFAULT/qpid_heartbeat': value => $::trove::qpid_heartbeat; + 'DEFAULT/qpid_protocol': value => $::trove::qpid_protocol; + 'DEFAULT/qpid_tcp_nodelay': value => $::trove::qpid_tcp_nodelay; + } + if is_array($::trove::qpid_sasl_mechanisms) { + trove_config { + 'DEFAULT/qpid_sasl_mechanisms': value => join($::trove::qpid_sasl_mechanisms, ' '); + } + } + elsif $::trove::qpid_sasl_mechanisms { + trove_config { + 'DEFAULT/qpid_sasl_mechanisms': value => $::trove::qpid_sasl_mechanisms; + } + } + else { + trove_config { + 'DEFAULT/qpid_sasl_mechanisms': ensure => absent; + } + } + } + + trove::generic_service { 'api': + enabled => $enabled, + manage_service => $manage_service, + ensure_package => $ensure_package, + package_name => $::trove::params::api_package_name, + service_name => $::trove::params::api_service_name, + } +} diff --git a/trove/manifests/client.pp b/trove/manifests/client.pp new file mode 100644 index 000000000..91d4076d2 --- /dev/null +++ b/trove/manifests/client.pp @@ -0,0 +1,40 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# trove::client +# +# Manages the trove client package on systems +# +# === Parameters: +# +# [*package_ensure*] +# (optional) The state of the package +# Defaults to present +# +# +class trove::client ( + $package_ensure = present +) { + + include trove::params + + package { 'python-troveclient': + ensure => $package_ensure, + name => $::trove::params::client_package_name, + } + +} diff --git a/trove/manifests/conductor.pp b/trove/manifests/conductor.pp new file mode 100644 index 000000000..e9fad5f58 --- /dev/null +++ b/trove/manifests/conductor.pp @@ -0,0 +1,196 @@ +# == Class: trove::conductor +# +# Manages trove conductor package and service +# +# === Parameters: +# +# [*enabled*] +# (optional) Whether to enable the trove-conductor service +# Defaults to true +# +# [*manage_service*] +# (optional) Whether to start/stop the service +# Defaults to true +# +# [*ensure_package*] +# (optional) The state of the trove conductor package +# Defaults to 'present' +# +# [*verbose*] +# (optional) Rather to log the trove api service at verbose level. +# Default: false +# +# [*debug*] +# (optional) Rather to log the trove api service at debug level. +# Default: false +# +# [*log_file*] +# (optional) The path of file used for logging +# If set to boolean false, it will not log to any file. +# Default: /var/log/trove/trove-conductor.log +# +# [*log_dir*] +# (optional) directory to which trove logs are sent. +# If set to boolean false, it will not log to any directory. +# Defaults to '/var/log/trove' +# +# [*use_syslog*] +# (optional) Use syslog for logging. +# Defaults to false. +# +# [*log_facility*] +# (optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER'. +# +# [*auth_url*] +# (optional) Authentication URL. +# Defaults to 'http://localhost:5000/v2.0'. +# +# [*conductor_manager*] +# (optional) Trove conductor manager. +# Defaults to 'trove.conductor.manager.Manager'. +# +class trove::conductor( + $enabled = true, + $manage_service = true, + $ensure_package = 'present', + $verbose = false, + $debug = false, + $log_file = '/var/log/trove/trove-conductor.log', + $log_dir = '/var/log/trove', + $use_syslog = false, + $log_facility = 'LOG_USER', + $auth_url = 'http://localhost:5000/v2.0', + $conductor_manager = 'trove.conductor.manager.Manager', +) inherits trove { + + include trove::params + + Package[$::trove::params::conductor_package_name] -> Trove_conductor_config<||> + Trove_conductor_config<||> ~> Exec['post-trove_config'] + Trove_conductor_config<||> ~> Service['trove-conductor'] + + if $::trove::database_connection { + if($::trove::database_connection =~ /mysql:\/\/\S+:\S+@\S+\/\S+/) { + require 'mysql::bindings' + require 'mysql::bindings::python' + } elsif($::trove::database_connection =~ /postgresql:\/\/\S+:\S+@\S+\/\S+/) { + + } elsif($::trove::database_connection =~ /sqlite:\/\//) { + + } else { + fail("Invalid db connection ${::trove::database_connection}") + } + trove_conductor_config { + 'DEFAULT/sql_connection': value => $::trove::database_connection; + } + } + + # basic service config + trove_conductor_config { + 'DEFAULT/verbose': value => $verbose; + 'DEFAULT/debug': value => $debug; + 'DEFAULT/trove_auth_url': value => $auth_url; + 'DEFAULT/nova_proxy_admin_user': value => $::trove::nova_proxy_admin_user; + 'DEFAULT/nova_proxy_admin_tenant_name': value => $::trove::nova_proxy_admin_tenant_name; + 'DEFAULT/nova_proxy_admin_pass': value => $::trove::nova_proxy_admin_pass; + 'DEFAULT/control_exchange': value => $::trove::control_exchange; + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + # I may want to support exporting and collecting these + trove_conductor_config { + 'DEFAULT/rabbit_password': value => $::trove::rabbit_password, secret => true; + 'DEFAULT/rabbit_userid': value => $::trove::rabbit_userid; + 'DEFAULT/rabbit_virtual_host': value => $::trove::rabbit_virtual_host; + 'DEFAULT/rabbit_use_ssl': value => $::trove::rabbit_use_ssl; + 'DEFAULT/amqp_durable_queues': value => $::trove::amqp_durable_queues; + 'DEFAULT/rabbit_notification_topic': value => $::trove::rabbit_notification_topic; + } + + if $::trove::rabbit_use_ssl { + trove_conductor_config { + 'DEFAULT/kombu_ssl_ca_certs': value => $::trove::kombu_ssl_ca_certs; + 'DEFAULT/kombu_ssl_certfile': value => $::trove::kombu_ssl_certfile; + 'DEFAULT/kombu_ssl_keyfile': value => $::trove::kombu_ssl_keyfile; + 'DEFAULT/kombu_ssl_version': value => $::trove::kombu_ssl_version; + } + } else { + trove_conductor_config { + 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'DEFAULT/kombu_ssl_version': ensure => absent; + } + } + + if $::trove::rabbit_hosts { + trove_conductor_config { 'DEFAULT/rabbit_hosts': value => join($::trove::rabbit_hosts, ',') } + trove_conductor_config { 'DEFAULT/rabbit_ha_queues': value => true } + } else { + trove_conductor_config { 'DEFAULT/rabbit_host': value => $::trove::rabbit_host } + trove_conductor_config { 'DEFAULT/rabbit_port': value => $::trove::rabbit_port } + trove_conductor_config { 'DEFAULT/rabbit_hosts': value => "${::trove::rabbit_host}:${::trove::rabbit_port}" } + trove_conductor_config { 'DEFAULT/rabbit_ha_queues': value => false } + } + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + trove_conductor_config { + 'DEFAULT/qpid_hostname': value => $::trove::qpid_hostname; + 'DEFAULT/qpid_port': value => $::trove::qpid_port; + 'DEFAULT/qpid_username': value => $::trove::qpid_username; + 'DEFAULT/qpid_password': value => $::trove::qpid_password, secret => true; + 'DEFAULT/qpid_heartbeat': value => $::trove::qpid_heartbeat; + 'DEFAULT/qpid_protocol': value => $::trove::qpid_protocol; + 'DEFAULT/qpid_tcp_nodelay': value => $::trove::qpid_tcp_nodelay; + } + if is_array($::trove::qpid_sasl_mechanisms) { + trove_conductor_config { + 'DEFAULT/qpid_sasl_mechanisms': value => join($::trove::qpid_sasl_mechanisms, ' '); + } + } + } + + # Logging + if $log_file { + trove_conductor_config { + 'DEFAULT/log_file': value => $log_file; + } + } else { + trove_conductor_config { + 'DEFAULT/log_file': ensure => absent; + } + } + + if $log_dir { + trove_conductor_config { + 'DEFAULT/log_dir': value => $log_dir; + } + } else { + trove_conductor_config { + 'DEFAULT/log_dir': ensure => absent; + } + } + + # Syslog + if $use_syslog { + trove_conductor_config { + 'DEFAULT/use_syslog' : value => true; + 'DEFAULT/syslog_log_facility' : value => $log_facility; + } + } else { + trove_conductor_config { + 'DEFAULT/use_syslog': value => false; + } + } + + trove::generic_service { 'conductor': + enabled => $enabled, + manage_service => $manage_service, + package_name => $::trove::params::conductor_package_name, + service_name => $::trove::params::conductor_service_name, + ensure_package => $ensure_package, + } + +} diff --git a/trove/manifests/db/mysql.pp b/trove/manifests/db/mysql.pp new file mode 100644 index 000000000..a20bc5ecc --- /dev/null +++ b/trove/manifests/db/mysql.pp @@ -0,0 +1,83 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: trove::db::mysql +# +# The trove::db::mysql class creates a MySQL database for trove. +# It must be used on the MySQL server +# +# === Parameters +# +# [*password*] +# (required) Password that will be used for the trove db user. +# +# [*dbname*] +# (optional) Name of trove database. +# Defaults to trove +# +# [*user*] +# (optional) Name of trove user. +# Defaults to trove +# +# [*host*] +# (optional) Host where user should be allowed all privileges for database. +# Defaults to 127.0.0.1 +# +# [*allowed_hosts*] +# (optional) Hosts allowed to use the database +# Defaults to undef. +# +# [*charset*] +# (optional) Charset of trove database +# Defaults 'utf8'. +# +# [*collate*] +# (optional) Charset collate of trove database +# Defaults 'utf8_unicode_ci'. +# +# [*mysql_module*] +# (optional) Deprecated. Does nothing +# +class trove::db::mysql( + $password, + $dbname = 'trove', + $user = 'trove', + $host = '127.0.0.1', + $allowed_hosts = undef, + $charset = 'utf8', + $collate = 'utf8_unicode_ci', + $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 { 'trove': + user => $user, + password_hash => mysql_password($password), + dbname => $dbname, + host => $host, + charset => $charset, + collate => $collate, + allowed_hosts => $allowed_hosts, + } + + ::Openstacklib::Db::Mysql['trove'] ~> Exec<| title == 'trove-db-sync' |> +} diff --git a/trove/manifests/db/postgresql.pp b/trove/manifests/db/postgresql.pp new file mode 100644 index 000000000..45f7a96a0 --- /dev/null +++ b/trove/manifests/db/postgresql.pp @@ -0,0 +1,36 @@ +# == Class: trove::db::postgresql +# +# Manage the trove postgresql database +# +# === Parameters: +# +# [*password*] +# (required) Password that will be used for the trove db user. +# +# [*dbname*] +# (optionnal) Name of trove database. +# Defaults to trove +# +# [*user*] +# (optionnal) Name of trove user. +# Defaults to trove +# +class trove::db::postgresql( + $password, + $dbname = 'trove', + $user = 'trove' +) { + + require postgresql::python + + Class['trove::db::postgresql'] -> Service<| title == 'trove' |> + Postgresql::Db[$dbname] ~> Exec<| title == 'trove-manage db_sync' |> + Package['python-psycopg2'] -> Exec<| title == 'trove-manage db_sync' |> + + + postgresql::db { $dbname: + user => $user, + password => $password, + } + +} diff --git a/trove/manifests/db/sync.pp b/trove/manifests/db/sync.pp new file mode 100644 index 000000000..2d39ee52f --- /dev/null +++ b/trove/manifests/db/sync.pp @@ -0,0 +1,27 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Class to execute "trove-manage db_sync +# +class trove::db::sync { + exec { 'trove-manage db_sync': + path => '/usr/bin', + user => 'trove', + refreshonly => true, + subscribe => Trove_config['DEFAULT/sql_connection'], + } +} diff --git a/trove/manifests/generic_service.pp b/trove/manifests/generic_service.pp new file mode 100644 index 000000000..9727bc6fe --- /dev/null +++ b/trove/manifests/generic_service.pp @@ -0,0 +1,71 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Define: trove::generic_service +# +# This defined type implements basic trove services. +# It is introduced to attempt to consolidate +# common code. +# +# It also allows users to specify ad-hoc services +# as needed +# +# This define creates a service resource with title trove-${name} and +# conditionally creates a package resource with title trove-${name} +# +define trove::generic_service( + $package_name, + $service_name, + $enabled = false, + $manage_service = true, + $ensure_package = 'present' +) { + + include trove::params + include trove::db::sync + + $trove_title = "trove-${name}" + Exec['post-trove_config'] ~> Service<| title == $trove_title |> + Exec<| title == 'trove-db-sync' |> ~> Service<| title == $trove_title |> + + if ($package_name) { + if !defined(Package[$package_name]) { + package { $trove_title: + ensure => $ensure_package, + name => $package_name, + notify => Service[$trove_title], + } + } + } + + if $service_name { + if $manage_service { + if $enabled { + $service_ensure = 'running' + } else { + $service_ensure = 'stopped' + } + } + + service { $trove_title: + ensure => $service_ensure, + name => $service_name, + enable => $enabled, + hasstatus => true, + } + } +} diff --git a/trove/manifests/guestagent.pp b/trove/manifests/guestagent.pp new file mode 100644 index 000000000..adc64aa9e --- /dev/null +++ b/trove/manifests/guestagent.pp @@ -0,0 +1,190 @@ +# == Class: trove::guestagent +# +# Manages trove guest agent package and service +# +# === Parameters: +# +# [*enabled*] +# (optional) Whether to enable the trove guest agent service +# Defaults to true +# +# [*manage_service*] +# (optional) Whether to start/stop the service +# Defaults to true +# +# [*ensure_package*] +# (optional) The state of the trove guest agent package +# Defaults to 'present' +# +# [*verbose*] +# (optional) Rather to log the trove guest agent service at verbose level. +# Default: false +# +# [*debug*] +# (optional) Rather to log the trove guest agent service at debug level. +# Default: false +# +# [*log_file*] +# (optional) The path of file used for logging +# If set to boolean false, it will not log to any file. +# Default: /var/log/trove/guestagent.log +# +# [*log_dir*] +# (optional) directory to which trove logs are sent. +# If set to boolean false, it will not log to any directory. +# Defaults to '/var/log/trove' +# +# [*use_syslog*] +# (optional) Use syslog for logging. +# Defaults to false. +# +# [*log_facility*] +# (optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER'. +# +# [*auth_url*] +# (optional) Authentication URL. +# Defaults to 'http://localhost:5000/v2.0'. +# +# [*swift_url*] +# (optional) Swift URL. +# Defaults to 'http://localhost:8080/v1/AUTH_'. +# +# [*control_exchange*] +# (optional) Control exchange. +# Defaults to 'trove'. +# +class trove::guestagent( + $enabled = true, + $manage_service = true, + $ensure_package = 'present', + $verbose = false, + $debug = false, + $log_file = '/var/log/trove/guestagent.log', + $log_dir = '/var/log/trove', + $use_syslog = false, + $log_facility = 'LOG_USER', + $auth_url = 'http://localhost:5000/v2.0', + $swift_url = 'http://localhost:8080/v1/AUTH_', + $control_exchange = 'trove' +) inherits trove { + + include trove::params + + Package[$::trove::params::guestagent_package_name] -> Trove_guestagent_config<||> + Trove_guestagent_config<||> ~> Exec['post-trove_config'] + Trove_guestagent_config<||> ~> Service['trove-guestagent'] + + # basic service config + trove_guestagent_config { + 'DEFAULT/verbose': value => $verbose; + 'DEFAULT/debug': value => $debug; + 'DEFAULT/trove_auth_url': value => $auth_url; + 'DEFAULT/swift_url': value => $swift_url; + 'DEFAULT/nova_proxy_admin_user': value => $::trove::nova_proxy_admin_user; + 'DEFAULT/nova_proxy_admin_tenant_name': value => $::trove::nova_proxy_admin_tenant_name; + 'DEFAULT/nova_proxy_admin_pass': value => $::trove::nova_proxy_admin_pass; + 'DEFAULT/control_exchange': value => $control_exchange; + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + # I may want to support exporting and collecting these + trove_guestagent_config { + 'DEFAULT/rabbit_password': value => $::trove::rabbit_password, secret => true; + 'DEFAULT/rabbit_userid': value => $::trove::rabbit_userid; + 'DEFAULT/rabbit_virtual_host': value => $::trove::rabbit_virtual_host; + 'DEFAULT/rabbit_use_ssl': value => $::trove::rabbit_use_ssl; + 'DEFAULT/amqp_durable_queues': value => $::trove::amqp_durable_queues; + 'DEFAULT/rabbit_notification_topic': value => $::trove::rabbit_notification_topic; + } + + if $::trove::rabbit_use_ssl { + trove_guestagent_config { + 'DEFAULT/kombu_ssl_ca_certs': value => $::trove::kombu_ssl_ca_certs; + 'DEFAULT/kombu_ssl_certfile': value => $::trove::kombu_ssl_certfile; + 'DEFAULT/kombu_ssl_keyfile': value => $::trove::kombu_ssl_keyfile; + 'DEFAULT/kombu_ssl_version': value => $::trove::kombu_ssl_version; + } + } else { + trove_guestagent_config { + 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'DEFAULT/kombu_ssl_version': ensure => absent; + } + } + + if $::trove::rabbit_hosts { + trove_guestagent_config { + 'DEFAULT/rabbit_hosts': value => join($::trove::rabbit_hosts, ','); + 'DEFAULT/rabbit_ha_queues': value => true + } + } else { + trove_guestagent_config { + 'DEFAULT/rabbit_host': value => $::trove::rabbit_host; + 'DEFAULT/rabbit_port': value => $::trove::rabbit_port; + 'DEFAULT/rabbit_hosts': value => "${::trove::rabbit_host}:${::trove::rabbit_port}"; + 'DEFAULT/rabbit_ha_queues': value => false + } + } + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + trove_guestagent_config { + 'DEFAULT/qpid_hostname': value => $::trove::qpid_hostname; + 'DEFAULT/qpid_port': value => $::trove::qpid_port; + 'DEFAULT/qpid_username': value => $::trove::qpid_username; + 'DEFAULT/qpid_password': value => $::trove::qpid_password, secret => true; + 'DEFAULT/qpid_heartbeat': value => $::trove::qpid_heartbeat; + 'DEFAULT/qpid_protocol': value => $::trove::qpid_protocol; + 'DEFAULT/qpid_tcp_nodelay': value => $::trove::qpid_tcp_nodelay; + } + if is_array($::trove::qpid_sasl_mechanisms) { + trove_guestagent_config { + 'DEFAULT/qpid_sasl_mechanisms': value => join($::trove::qpid_sasl_mechanisms, ' '); + } + } + } + + # Logging + if $log_file { + trove_guestagent_config { + 'DEFAULT/log_file': value => $log_file; + } + } else { + trove_guestagent_config { + 'DEFAULT/log_file': ensure => absent; + } + } + + if $log_dir { + trove_guestagent_config { + 'DEFAULT/log_dir': value => $log_dir; + } + } else { + trove_guestagent_config { + 'DEFAULT/log_dir': ensure => absent; + } + } + + # Syslog + if $use_syslog { + trove_guestagent_config { + 'DEFAULT/use_syslog' : value => true; + 'DEFAULT/syslog_log_facility' : value => $log_facility; + } + } else { + trove_guestagent_config { + 'DEFAULT/use_syslog': value => false; + } + } + + trove::generic_service { 'guestagent': + enabled => $enabled, + manage_service => $manage_service, + package_name => $::trove::params::guestagent_package_name, + service_name => $::trove::params::guestagent_service_name, + ensure_package => $ensure_package, + } + +} diff --git a/trove/manifests/init.pp b/trove/manifests/init.pp new file mode 100644 index 000000000..52f5eff63 --- /dev/null +++ b/trove/manifests/init.pp @@ -0,0 +1,203 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# trove::init +# +# Trove base config +# +# == Parameters +# +# [*rabbit_host*] +# (optional) Location of rabbitmq installation. +# Defaults to 'localhost' +# +# [*rabbit_hosts*] +# (optional) List of clustered rabbit servers. +# Defaults to false +# +# [*rabbit_port*] +# (optional) Port for rabbitmq instance. +# Defaults to '5672' +# +# [*rabbit_password*] +# (optional) Password used to connect to rabbitmq. +# Defaults to 'guest' +# +# [*rabbit_userid*] +# (optional) User used to connect to rabbitmq. +# Defaults to 'guest' +# +# [*rabbit_virtual_host*] +# (optional) The RabbitMQ virtual host. +# Defaults to '/' +# +# [*rabbit_use_ssl*] +# (optional) Connect over SSL for RabbitMQ +# Defaults to false +# +# [*rabbit_notification_topic*] +# (optional) Notification topic. +# Defaults to false. +# +# [*kombu_ssl_ca_certs*] +# (optional) SSL certification authority file (valid only if SSL enabled). +# Defaults to undef +# +# [*kombu_ssl_certfile*] +# (optional) SSL cert file (valid only if SSL enabled). +# Defaults to undef +# +# [*kombu_ssl_keyfile*] +# (optional) SSL key file (valid only if SSL enabled). +# Defaults to undef +# +# [*kombu_ssl_version*] +# (optional) SSL version to use (valid only if SSL enabled). +# Valid values are TLSv1, SSLv23 and SSLv3. SSLv2 may be +# available on some distributions. +# Defaults to 'SSLv3' +# +# [*amqp_durable_queues*] +# (optional) Define queues as "durable" to rabbitmq. +# Defaults to false +# +# [*qpid_hostname*] +# (optional) Location of qpid server +# Defaults to 'localhost' +# +# [*qpid_port*] +# (optional) Port for qpid server +# Defaults to '5672' +# +# [*qpid_username*] +# (optional) Username to use when connecting to qpid +# Defaults to 'guest' +# +# [*qpid_password*] +# (optional) Password to use when connecting to qpid +# Defaults to 'guest' +# +# [*qpid_heartbeat*] +# (optional) Seconds between connection keepalive heartbeats +# Defaults to 60 +# +# [*qpid_protocol*] +# (optional) Transport to use, either 'tcp' or 'ssl'' +# Defaults to 'tcp' +# +# [*qpid_sasl_mechanisms*] +# (optional) Enable one or more SASL mechanisms +# Defaults to false +# +# [*qpid_tcp_nodelay*] +# (optional) Disable Nagle algorithm +# Defaults to true +# +# [*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' +# +# [*mysql_module*] +# (optional) Deprecated. Does nothing. +# Defaults to undef. +# +# [*database_connection*] +# (optional) Connection url to connect to trove database. +# Defaults to 'sqlite:////var/lib/trove/trove.sqlite' +# +# [*database_idle_timeout*] +# (optional) Timeout before idle db connections are reaped. +# Defaults to 3600 +# +# [*nova_proxy_admin_user*] +# (optional) Admin username used to connect to nova. +# Defaults to 'admin' +# +# [*nova_proxy_admin_pass*] +# (required) Admin password used to connect to nova. +# +# [*nova_proxy_admin_tenant_name*] +# (optional) Admin tenant name used to connect to nova. +# Defaults to 'admin' +# +# [*control_exchange*] +# (optional) Control exchange. +# Defaults to 'trove'. +# +class trove( + $nova_proxy_admin_pass, + $rabbit_host = 'localhost', + $rabbit_hosts = false, + $rabbit_password = 'guest', + $rabbit_port = '5672', + $rabbit_userid = 'guest', + $rabbit_virtual_host = '/', + $rabbit_use_ssl = false, + $rabbit_notification_topic = 'notifications', + $kombu_ssl_ca_certs = undef, + $kombu_ssl_certfile = undef, + $kombu_ssl_keyfile = undef, + $kombu_ssl_version = 'SSLv3', + $amqp_durable_queues = false, + $database_connection = 'sqlite:////var/lib/trove/trove.sqlite', + $database_idle_timeout = 3600, + $rpc_backend = 'trove.openstack.common.rpc.impl_kombu', + $nova_compute_url = false, + $nova_proxy_admin_user = 'admin', + $nova_proxy_admin_tenant_name = 'admin', + $control_exchange = 'trove', + $cinder_url = false, + $swift_url = false, + # DEPRECATED PARAMETERS + $mysql_module = undef, +) { + include trove::params + + if $mysql_module { + warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.') + } + + exec { 'post-trove_config': + command => '/bin/echo "Trove config has changed"', + refreshonly => true, + } + + Trove_datastore<||> -> Trove_datastore_version<||> + + if $nova_compute_url { + trove_config { 'DEFAULT/nova_compute_url': value => $nova_compute_url } + } + else { + trove_config { 'DEFAULT/nova_compute_url': ensure => absent } + } + + if $cinder_url { + trove_config { 'DEFAULT/cinder_url': value => $cinder_url } + } + else { + trove_config { 'DEFAULT/cinder_url': ensure => absent } + } + + if $swift_url { + trove_config { 'DEFAULT/swift_url': value => $swift_url } + } + else { + trove_config { 'DEFAULT/swift_url': ensure => absent } + } +} diff --git a/trove/manifests/keystone/auth.pp b/trove/manifests/keystone/auth.pp new file mode 100644 index 000000000..97abd5525 --- /dev/null +++ b/trove/manifests/keystone/auth.pp @@ -0,0 +1,112 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# trove::keystone::auth +# +# Configures Trove user, service and endpoint in Keystone. +# +# === Parameters +# +# [*password*] +# (required) Password for Trove user. +# +# [*auth_name*] +# Username for Trove service. Defaults to 'trove'. +# +# [*email*] +# Email for Trove user. Defaults to 'trove@localhost'. +# +# [*tenant*] +# Tenant for Trove user. Defaults to 'services'. +# +# [*configure_endpoint*] +# Should Trove endpoint be configured? Defaults to 'true'. +# +# [*service_type*] +# Type of service. Defaults to 'database'. +# +# [*public_protocol*] +# Protocol for public endpoint. Defaults to 'http'. +# +# [*public_address*] +# Public address for endpoint. Defaults to '127.0.0.1'. +# +# [*admin_protocol*] +# Protocol for admin endpoint. Defaults to 'http'. +# +# [*admin_address*] +# Admin address for endpoint. Defaults to '127.0.0.1'. +# +# [*internal_protocol*] +# Protocol for internal endpoint. Defaults to 'http'. +# +# [*internal_address*] +# Internal address for endpoint. Defaults to '127.0.0.1'. +# +# [*port*] +# Port for endpoint. Defaults to '8779'. +# +# [*public_port*] +# Port for public endpoint. Defaults to $port. +# +# [*region*] +# Region for endpoint. Defaults to 'RegionOne'. +# +# +class trove::keystone::auth ( + $password, + $auth_name = 'trove', + $email = 'trove@localhost', + $tenant = 'services', + $configure_endpoint = true, + $service_type = 'database', + $public_protocol = 'http', + $public_address = '127.0.0.1', + $admin_protocol = 'http', + $admin_address = '127.0.0.1', + $internal_protocol = 'http', + $internal_address = '127.0.0.1', + $port = '8779', + $public_port = undef, + $region = 'RegionOne' +) { + + Keystone_user_role["${auth_name}@${tenant}"] ~> Service <| name == 'trove-server' |> + Keystone_endpoint["${region}/${auth_name}"] ~> Service <| name == 'trove-server' |> + + if ! $public_port { + $real_public_port = $port + } else { + $real_public_port = $public_port + } + + keystone::resource::service_identity { $auth_name: + configure_user => true, + configure_user_role => true, + configure_endpoint => $configure_endpoint, + service_type => $service_type, + service_description => 'Trove Database Service', + region => $region, + password => $password, + email => $email, + tenant => $tenant, + public_url => "${public_protocol}://${public_address}:${real_public_port}/v1.0/\$(tenant_id)s", + internal_url => "${internal_protocol}://${internal_address}:${port}/v1.0/\$(tenant_id)s", + admin_url => "${admin_protocol}://${admin_address}:${port}/v1.0/\$(tenant_id)s", + } + +} diff --git a/trove/manifests/params.pp b/trove/manifests/params.pp new file mode 100644 index 000000000..04120d20c --- /dev/null +++ b/trove/manifests/params.pp @@ -0,0 +1,33 @@ +# Parameters for puppet-trove +# +class trove::params { + + case $::osfamily { + 'RedHat': { + $client_package_name = 'openstack-trove' + $conductor_package_name = 'openstack-trove-conductor' + $conductor_service_name = 'openstack-trove-conductor' + $api_package_name = 'openstack-trove-api' + $api_service_name = 'openstack-trove-api' + $guestagent_package_name = 'openstack-trove-guestagent' + $guestagent_service_name = 'openstack-trove-guestagent' + $taskmanager_package_name = 'openstack-trove-taskmanager' + $taskmanager_service_name = 'openstack-trove-taskmanager' + } + 'Debian': { + $client_package_name = 'python-troveclient' + $conductor_package_name = 'trove-conductor' + $conductor_service_name = 'trove-conductor' + $api_package_name = 'trove-api' + $api_service_name = 'trove-api' + $guestagent_package_name = 'trove-guestagent' + $guestagent_service_name = 'trove-guestagent' + $taskmanager_package_name = 'trove-taskmanager' + $taskmanager_service_name = 'trove-taskmanager' + } + default: { + fail("Unsupported osfamily: ${::osfamily} operatingsystem") + } + + } # Case $::osfamily +} diff --git a/trove/manifests/taskmanager.pp b/trove/manifests/taskmanager.pp new file mode 100644 index 000000000..405df9a3f --- /dev/null +++ b/trove/manifests/taskmanager.pp @@ -0,0 +1,224 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: trove::taskmanager +# +# Manages trove taskmanager package and service +# +# === Parameters: +# +# [*enabled*] +# (optional) Whether to enable the trove-taskmanager service +# Defaults to true +# +# [*manage_service*] +# (optional) Whether to start/stop the service +# Defaults to true +# +# [*ensure_package*] +# (optional) The state of the trove taskmanager package +# Defaults to 'present' +# +# [*verbose*] +# (optional) Rather to log the trove api service at verbose level. +# Default: false +# +# [*debug*] +# (optional) Rather to log the trove api service at debug level. +# Default: false +# +# [*log_file*] +# (optional) The path of file used for logging +# If set to boolean false, it will not log to any file. +# Default: /var/log/trove/trove-taskmanager.log +# +# [*log_dir*] +# (optional) directory to which trove logs are sent. +# If set to boolean false, it will not log to any directory. +# Defaults to '/var/log/trove' +# +# [*use_syslog*] +# (optional) Use syslog for logging. +# Defaults to false. +# +# [*log_facility*] +# (optional) Syslog facility to receive log lines. +# Defaults to 'LOG_USER'. +# +# [*auth_url*] +# (optional) Authentication URL. +# Defaults to 'http://localhost:5000/v2.0'. +# +# [**guestagent_config_file*] +# (optional) Trove guest agent configuration file. +# Defaults to '/etc/trove/trove-guestmanager.conf'. +# + +class trove::taskmanager( + $enabled = true, + $manage_service = true, + $debug = false, + $verbose = false, + $log_file = '/var/log/trove/trove-taskmanager.log', + $log_dir = '/var/log/trove', + $use_syslog = false, + $log_facility = 'LOG_USER', + $auth_url = 'http://localhost:5000/v2.0', + $heat_url = false, + $ensure_package = 'present', + $guestagent_config_file = '/etc/trove/trove-guestmanager.conf' +) inherits trove { + + include trove::params + + Package[$::trove::params::taskmanager_package_name] -> Trove_taskmanager_config<||> + Trove_taskmanager_config<||> ~> Exec['post-trove_config'] + Trove_taskmanager_config<||> ~> Service['trove-taskmanager'] + + if $::trove::database_connection { + if($::trove::database_connection =~ /mysql:\/\/\S+:\S+@\S+\/\S+/) { + require 'mysql::bindings' + require 'mysql::bindings::python' + } elsif($::trove::database_connection =~ /postgresql:\/\/\S+:\S+@\S+\/\S+/) { + + } elsif($::trove::database_connection =~ /sqlite:\/\//) { + + } else { + fail("Invalid db connection ${::trove::database_connection}") + } + trove_taskmanager_config { + 'DEFAULT/sql_connection': value => $::trove::database_connection; + 'DEFAULT/sql_idle_timeout': value => $::trove::database_idle_timeoutl; + } + } + + # basic service config + trove_taskmanager_config { + 'DEFAULT/verbose': value => $verbose; + 'DEFAULT/debug': value => $debug; + 'DEFAULT/trove_auth_url': value => $auth_url; + 'DEFAULT/nova_proxy_admin_user': value => $::trove::nova_proxy_admin_user; + 'DEFAULT/nova_proxy_admin_pass': value => $::trove::nova_proxy_admin_pass; + 'DEFAULT/nova_proxy_admin_tenant_name': value => $::trove::nova_proxy_admin_tenant_name; + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_kombu' { + # I may want to support exporting and collecting these + trove_taskmanager_config { + 'DEFAULT/rabbit_password': value => $::trove::rabbit_password, secret => true; + 'DEFAULT/rabbit_userid': value => $::trove::rabbit_userid; + 'DEFAULT/rabbit_virtual_host': value => $::trove::rabbit_virtual_host; + 'DEFAULT/rabbit_use_ssl': value => $::trove::rabbit_use_ssl; + 'DEFAULT/amqp_durable_queues': value => $::trove::amqp_durable_queues; + } + + if $::trove::rabbit_use_ssl { + trove_taskmanager_config { + 'DEFAULT/kombu_ssl_ca_certs': value => $::trove::kombu_ssl_ca_certs; + 'DEFAULT/kombu_ssl_certfile': value => $::trove::kombu_ssl_certfile; + 'DEFAULT/kombu_ssl_keyfile': value => $::trove::kombu_ssl_keyfile; + 'DEFAULT/kombu_ssl_version': value => $::trove::kombu_ssl_version; + } + } else { + trove_taskmanager_config { + 'DEFAULT/kombu_ssl_ca_certs': ensure => absent; + 'DEFAULT/kombu_ssl_certfile': ensure => absent; + 'DEFAULT/kombu_ssl_keyfile': ensure => absent; + 'DEFAULT/kombu_ssl_version': ensure => absent; + } + } + + if $::trove::rabbit_hosts { + trove_taskmanager_config { 'DEFAULT/rabbit_hosts': value => join($::trove::rabbit_hosts, ',') } + trove_taskmanager_config { 'DEFAULT/rabbit_ha_queues': value => true } + } else { + trove_taskmanager_config { 'DEFAULT/rabbit_host': value => $::trove::rabbit_host } + trove_taskmanager_config { 'DEFAULT/rabbit_port': value => $::trove::rabbit_port } + trove_taskmanager_config { 'DEFAULT/rabbit_hosts': value => "${::trove::rabbit_host}:${::trove::rabbit_port}" } + trove_taskmanager_config { 'DEFAULT/rabbit_ha_queues': value => false } + } + } + + if $::trove::rpc_backend == 'trove.openstack.common.rpc.impl_qpid' { + trove_taskmanager_config { + 'DEFAULT/qpid_hostname': value => $::trove::qpid_hostname; + 'DEFAULT/qpid_port': value => $::trove::qpid_port; + 'DEFAULT/qpid_username': value => $::trove::qpid_username; + 'DEFAULT/qpid_password': value => $::trove::qpid_password, secret => true; + 'DEFAULT/qpid_heartbeat': value => $::trove::qpid_heartbeat; + 'DEFAULT/qpid_protocol': value => $::trove::qpid_protocol; + 'DEFAULT/qpid_tcp_nodelay': value => $::trove::qpid_tcp_nodelay; + } + if is_array($::trove::qpid_sasl_mechanisms) { + trove_taskmanager_config { + 'DEFAULT/qpid_sasl_mechanisms': value => join($::trove::qpid_sasl_mechanisms, ' '); + } + } + } + + # Logging + if $log_file { + trove_taskmanager_config { + 'DEFAULT/log_file': value => $log_file; + } + } else { + trove_taskmanager_config { + 'DEFAULT/log_file': ensure => absent; + } + } + + if $log_dir { + trove_taskmanager_config { + 'DEFAULT/log_dir': value => $log_dir; + } + } else { + trove_taskmanager_config { + 'DEFAULT/log_dir': ensure => absent; + } + } + + # Syslog + if $use_syslog { + trove_taskmanager_config { + 'DEFAULT/use_syslog' : value => true; + 'DEFAULT/syslog_log_facility' : value => $log_facility; + } + } else { + trove_taskmanager_config { + 'DEFAULT/use_syslog': value => false; + } + } + + trove::generic_service { 'taskmanager': + enabled => $enabled, + manage_service => $manage_service, + package_name => $::trove::params::taskmanager_package_name, + service_name => $::trove::params::taskmanager_service_name, + ensure_package => $ensure_package, + } + + if $guestagent_config_file { + file { $guestagent_config_file: + content => template('trove/trove-guestagent.conf.erb') + } + + trove_taskmanager_config { + 'DEFAULT/guest_config': value => $guestagent_config_file + } + } + +} diff --git a/trove/metadata.json b/trove/metadata.json new file mode 100644 index 000000000..66044c001 --- /dev/null +++ b/trove/metadata.json @@ -0,0 +1,39 @@ +{ + "name": "stackforge-trove", + "version": "5.0.0", + "author": "eNovance and StackForge Contributors", + "summary": "Puppet module for OpenStack Trove", + "license": "Apache License 2.0", + "source": "git://github.com/stackforge/puppet-trove.git", + "project_page": "https://launchpad.net/puppet-trove", + "issues_url": "https://bugs.launchpad.net/puppet-trove", + "requirements": [ + { "name": "pe","version_requirement": "3.x" }, + { "name": "puppet","version_requirement": "3.x" } + ], + "operatingsystem_support": [ + { + "operatingsystem": "Debian", + "operatingsystemrelease": ["7"] + }, + { + "operatingsystem": "Fedora", + "operatingsystemrelease": ["20"] + }, + { + "operatingsystem": "RedHat", + "operatingsystemrelease": ["6.5","7"] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": ["12.04","14.04"] + } + ], + "description": "Installs and configures OpenStack Trove (Database service).", + "dependencies": [ + { "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" }, + { "name": "stackforge/keystone", "version_requirement": ">=5.0.0 <6.0.0" }, + { "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" }, + { "name": "stackforge/openstacklib", "version_requirement": ">=5.0.0" } + ] +} diff --git a/trove/spec/classes/trove_api_spec.rb b/trove/spec/classes/trove_api_spec.rb new file mode 100644 index 000000000..b3e151fc7 --- /dev/null +++ b/trove/spec/classes/trove_api_spec.rb @@ -0,0 +1,140 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for trove::api +# +require 'spec_helper' + +describe 'trove::api' do + + let :params do + { :keystone_password => 'passw0rd', + :auth_host => '10.0.0.10', + :auth_url => 'http://10.0.0.10:5000/v2.0', + :auth_port => '35357', + :auth_protocol => 'https', + :keystone_tenant => '_services_', + :keystone_user => 'trove', + } + end + + shared_examples 'trove-api' do + + context 'with default parameters' do + + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete'}" + end + + it 'installs trove-api package and service' do + should contain_service('trove-api').with( + :name => platform_params[:api_service_name], + :ensure => 'running', + :hasstatus => true, + :enable => true + ) + should contain_package('trove-api').with( + :name => platform_params[:api_package_name], + :ensure => 'present', + :notify => 'Service[trove-api]' + ) + end + + it 'configures trove-api with default parameters' do + should contain_trove_config('DEFAULT/verbose').with_value(false) + should contain_trove_config('DEFAULT/debug').with_value(false) + should contain_trove_config('DEFAULT/bind_host').with_value('0.0.0.0') + should contain_trove_config('DEFAULT/bind_port').with_value('8779') + should contain_trove_config('DEFAULT/backlog').with_value('4096') + should contain_trove_config('DEFAULT/trove_api_workers').with_value('8') + should contain_trove_config('DEFAULT/trove_auth_url').with_value('http://10.0.0.10:5000/v2.0') + should contain_trove_config('DEFAULT/nova_proxy_admin_user').with_value('admin') + should contain_trove_config('DEFAULT/nova_proxy_admin_pass').with_value('verysecrete') + should contain_trove_config('DEFAULT/nova_proxy_admin_tenant_name').with_value('admin') + should contain_trove_api_paste_ini('filter:authtoken/auth_host').with_value('10.0.0.10') + should contain_trove_api_paste_ini('filter:authtoken/auth_port').with_value('35357') + should contain_trove_api_paste_ini('filter:authtoken/auth_protocol').with_value('https') + should contain_trove_api_paste_ini('filter:authtoken/admin_tenant_name').with_value('_services_') + should contain_trove_api_paste_ini('filter:authtoken/admin_user').with_value('trove') + should contain_trove_api_paste_ini('filter:authtoken/admin_password').with_value('passw0rd') + end + + context 'when using a single RabbitMQ server' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_host => '10.0.0.1'}" + end + it 'configures trove-api with RabbitMQ' do + should contain_trove_config('DEFAULT/rabbit_host').with_value('10.0.0.1') + end + end + + context 'when using multiple RabbitMQ servers' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_hosts => ['10.0.0.1','10.0.0.2']}" + end + it 'configures trove-api with RabbitMQ' do + should contain_trove_config('DEFAULT/rabbit_hosts').with_value(['10.0.0.1,10.0.0.2']) + end + end + + context 'when using MySQL' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + database_connection => 'mysql://trove:pass@10.0.0.1/trove'}" + end + it 'configures trove-api with RabbitMQ' do + should contain_trove_config('DEFAULT/sql_connection').with_value('mysql://trove:pass@10.0.0.1/trove') + end + end + end + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian', + :processorcount => 8 } + end + + let :platform_params do + { :api_package_name => 'trove-api', + :api_service_name => 'trove-api' } + end + + it_configures 'trove-api' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat', + :processorcount => 8 } + end + + let :platform_params do + { :api_package_name => 'openstack-trove-api', + :api_service_name => 'openstack-trove-api' } + end + + it_configures 'trove-api' + end + +end diff --git a/trove/spec/classes/trove_client_spec.rb b/trove/spec/classes/trove_client_spec.rb new file mode 100644 index 000000000..170c611fa --- /dev/null +++ b/trove/spec/classes/trove_client_spec.rb @@ -0,0 +1,55 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for trove::client +# + +require 'spec_helper' + +describe 'trove::client' do + + shared_examples_for 'trove client' do + + context 'with default parameters' do + it { should contain_package('python-troveclient').with_ensure('present') } + end + + context 'with package_ensure parameter provided' do + let :params do + { :package_ensure => false } + end + it { should contain_package('python-troveclient').with_ensure('false') } + end + + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'trove client' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'trove client' + end +end diff --git a/trove/spec/classes/trove_conductor_spec.rb b/trove/spec/classes/trove_conductor_spec.rb new file mode 100644 index 000000000..8f62d0d1b --- /dev/null +++ b/trove/spec/classes/trove_conductor_spec.rb @@ -0,0 +1,99 @@ +require 'spec_helper' + +describe 'trove::conductor' do + + shared_examples 'trove-conductor' do + + context 'with default parameters' do + + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete'}" + end + + it 'installs trove-conductor package and service' do + should contain_service('trove-conductor').with( + :name => platform_params[:conductor_service_name], + :ensure => 'running', + :hasstatus => true, + :enable => true + ) + should contain_package('trove-conductor').with( + :name => platform_params[:conductor_package_name], + :ensure => 'present', + :notify => 'Service[trove-conductor]' + ) + end + + it 'configures trove-conductor with default parameters' do + should contain_trove_conductor_config('DEFAULT/verbose').with_value(false) + should contain_trove_conductor_config('DEFAULT/debug').with_value(false) + should contain_trove_conductor_config('DEFAULT/nova_proxy_admin_user').with_value('admin') + should contain_trove_conductor_config('DEFAULT/nova_proxy_admin_pass').with_value('verysecrete') + should contain_trove_conductor_config('DEFAULT/nova_proxy_admin_tenant_name').with_value('admin') + end + + context 'when using a single RabbitMQ server' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_host => '10.0.0.1'}" + end + it 'configures trove-conductor with RabbitMQ' do + should contain_trove_conductor_config('DEFAULT/rabbit_host').with_value('10.0.0.1') + end + end + + context 'when using multiple RabbitMQ servers' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_hosts => ['10.0.0.1','10.0.0.2']}" + end + it 'configures trove-conductor with RabbitMQ' do + should contain_trove_conductor_config('DEFAULT/rabbit_hosts').with_value(['10.0.0.1,10.0.0.2']) + end + end + + context 'when using MySQL' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + database_connection => 'mysql://trove:pass@10.0.0.1/trove'}" + end + it 'configures trove-conductor with RabbitMQ' do + should contain_trove_conductor_config('DEFAULT/sql_connection').with_value('mysql://trove:pass@10.0.0.1/trove') + end + end + end + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian', + :processorcount => 8 } + end + + let :platform_params do + { :conductor_package_name => 'trove-conductor', + :conductor_service_name => 'trove-conductor' } + end + + it_configures 'trove-conductor' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat', + :processorcount => 8 } + end + + let :platform_params do + { :conductor_package_name => 'openstack-trove-conductor', + :conductor_service_name => 'openstack-trove-conductor' } + end + + it_configures 'trove-conductor' + end + +end diff --git a/trove/spec/classes/trove_db_mysql_spec.rb b/trove/spec/classes/trove_db_mysql_spec.rb new file mode 100644 index 000000000..541189c3a --- /dev/null +++ b/trove/spec/classes/trove_db_mysql_spec.rb @@ -0,0 +1,109 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +require 'spec_helper' + +describe 'trove::db::mysql' do + + let :pre_condition do + [ + 'include mysql::server', + 'include trove::db::sync' + ] + end + + let :params do + { :dbname => 'trove', + :password => 's3cr3t', + :user => 'trove', + :charset => 'utf8', + :collate => 'utf8_unicode_ci', + :host => '127.0.0.1', + } + end + + shared_examples_for 'trove mysql database' do + + context 'when omiting the required parameter password' do + before { params.delete(:password) } + it { expect { should raise_error(Puppet::Error) } } + end + + it 'creates a mysql database' do + should contain_openstacklib__db__mysql('trove').with( + :user => params[:user], + :dbname => params[:dbname], + :password_hash => '*58C036CDA51D8E8BBBBF2F9EA5ABF111ADA444F0', + :host => params[:host], + :charset => params[:charset] + ) + end + + context 'overriding allowed_hosts param to array' do + before :each do + params.merge!( + :allowed_hosts => ['127.0.0.1','%'] + ) + end + + it { + should contain_openstacklib__db__mysql('trove').with( + :user => params[:user], + :dbname => params[:dbname], + :password_hash => '*58C036CDA51D8E8BBBBF2F9EA5ABF111ADA444F0', + :host => params[:host], + :charset => params[:charset], + :allowed_hosts => ['127.0.0.1','%'] + )} + end + + context 'overriding allowed_hosts param to string' do + before :each do + params.merge!( + :allowed_hosts => '192.168.1.1' + ) + end + + it { + should contain_openstacklib__db__mysql('trove').with( + :user => params[:user], + :dbname => params[:dbname], + :password_hash => '*58C036CDA51D8E8BBBBF2F9EA5ABF111ADA444F0', + :host => params[:host], + :charset => params[:charset], + :allowed_hosts => '192.168.1.1' + )} + end + + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'trove mysql database' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'trove mysql database' + end +end diff --git a/trove/spec/classes/trove_db_postgresql_spec.rb b/trove/spec/classes/trove_db_postgresql_spec.rb new file mode 100644 index 000000000..6f1d1f407 --- /dev/null +++ b/trove/spec/classes/trove_db_postgresql_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe 'trove::db::postgresql' do + + let :req_params do + {:password => 'pw'} + end + + let :facts do + { + :postgres_default_version => '8.4', + :osfamily => 'RedHat', + } + end + + describe 'with only required params' do + let :params do + req_params + end + it { should contain_postgresql__db('trove').with( + :user => 'trove', + :password => 'pw' + ) } + end + +end diff --git a/trove/spec/classes/trove_guestagent_spec.rb b/trove/spec/classes/trove_guestagent_spec.rb new file mode 100644 index 000000000..238c07359 --- /dev/null +++ b/trove/spec/classes/trove_guestagent_spec.rb @@ -0,0 +1,105 @@ +require 'spec_helper' + +describe 'trove::guestagent' do + + shared_examples 'trove-guestagent' do + + context 'with default parameters' do + + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete'}" + end + + it 'installs trove-guestagent package and service' do + should contain_service('trove-guestagent').with( + :name => platform_params[:guestagent_service_name], + :ensure => 'running', + :hasstatus => true, + :enable => true + ) + should contain_package('trove-guestagent').with( + :name => platform_params[:guestagent_package_name], + :ensure => 'present', + :notify => 'Service[trove-guestagent]' + ) + end + + it 'configures trove-guestagent with default parameters' do + should contain_trove_guestagent_config('DEFAULT/verbose').with_value(false) + should contain_trove_guestagent_config('DEFAULT/debug').with_value(false) + should contain_trove_guestagent_config('DEFAULT/nova_proxy_admin_user').with_value('admin') + should contain_trove_guestagent_config('DEFAULT/nova_proxy_admin_pass').with_value('verysecrete') + should contain_trove_guestagent_config('DEFAULT/nova_proxy_admin_tenant_name').with_value('admin') + end + + context 'when using a single RabbitMQ server' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_host => '10.0.0.1'}" + end + it 'configures trove-guestagent with RabbitMQ' do + should contain_trove_guestagent_config('DEFAULT/rabbit_host').with_value('10.0.0.1') + end + end + + context 'when using multiple RabbitMQ servers' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_hosts => ['10.0.0.1','10.0.0.2']}" + end + it 'configures trove-guestagent with RabbitMQ' do + should contain_trove_guestagent_config('DEFAULT/rabbit_hosts').with_value(['10.0.0.1,10.0.0.2']) + end + end + end + + context 'with custom parameters' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete'}" + end + + let :params do + { :auth_url => "http://10.0.0.1:5000/v2.0", + :swift_url => "http://10.0.0.1:8080/v1/AUTH_" } + end + it 'configures trove-guestagent with custom parameters' do + should contain_trove_guestagent_config('DEFAULT/trove_auth_url').with_value('http://10.0.0.1:5000/v2.0') + should contain_trove_guestagent_config('DEFAULT/swift_url').with_value('http://10.0.0.1:8080/v1/AUTH_') + end + end + + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian', + :processorcount => 8 } + end + + let :platform_params do + { :guestagent_package_name => 'trove-guestagent', + :guestagent_service_name => 'trove-guestagent' } + end + + it_configures 'trove-guestagent' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat', + :processorcount => 8 } + end + + let :platform_params do + { :guestagent_package_name => 'openstack-trove-guestagent', + :guestagent_service_name => 'openstack-trove-guestagent' } + end + + it_configures 'trove-guestagent' + end + +end diff --git a/trove/spec/classes/trove_init_spec.rb b/trove/spec/classes/trove_init_spec.rb new file mode 100644 index 000000000..6430aba51 --- /dev/null +++ b/trove/spec/classes/trove_init_spec.rb @@ -0,0 +1,56 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for trove::init +# + +require 'spec_helper' + +describe 'trove' do + + let :params do + { :nova_proxy_admin_pass => 'passw0rd', + :nova_compute_url => 'http://localhost:8774/v2', + :cinder_url => 'http://localhost:8776/v1', + :swift_url => 'http://localhost:8080/v1/AUTH_' } + end + + shared_examples_for 'trove' do + it { + should contain_class('trove::params') + should contain_trove_config('DEFAULT/nova_compute_url').with_value('http://localhost:8774/v2') + should contain_trove_config('DEFAULT/cinder_url').with_value('http://localhost:8776/v1') + should contain_trove_config('DEFAULT/swift_url').with_value('http://localhost:8080/v1/AUTH_') + } + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian' } + end + + it_configures 'trove' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat' } + end + + it_configures 'trove' + end +end diff --git a/trove/spec/classes/trove_keystone_auth_spec.rb b/trove/spec/classes/trove_keystone_auth_spec.rb new file mode 100644 index 000000000..a36c875fa --- /dev/null +++ b/trove/spec/classes/trove_keystone_auth_spec.rb @@ -0,0 +1,101 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for trove::keystone::auth +# + +require 'spec_helper' + +describe 'trove::keystone::auth' do + + let :facts do + { :osfamily => 'Debian' } + end + + describe 'with default class parameters' do + let :params do + { :password => 'trove_password', + :tenant => 'foobar' } + end + + it { should contain_keystone_user('trove').with( + :ensure => 'present', + :password => 'trove_password', + :tenant => 'foobar' + ) } + + it { should contain_keystone_user_role('trove@foobar').with( + :ensure => 'present', + :roles => 'admin' + )} + + it { should contain_keystone_service('trove').with( + :ensure => 'present', + :type => 'database', + :description => 'Trove Database Service' + ) } + + it { should contain_keystone_endpoint('RegionOne/trove').with( + :ensure => 'present', + :public_url => "http://127.0.0.1:8779/v1.0/\$(tenant_id)s", + :admin_url => "http://127.0.0.1:8779/v1.0/\$(tenant_id)s", + :internal_url => "http://127.0.0.1:8779/v1.0/\$(tenant_id)s" + ) } + end + + describe 'when configuring trove-server' do + let :pre_condition do + "class { 'trove::server': auth_password => 'test' }" + end + + let :params do + { :password => 'trove_password', + :tenant => 'foobar' } + end + end + + describe 'when overriding public_protocol, public_port and public address' do + let :params do + { :password => 'trove_password', + :public_protocol => 'https', + :public_port => '80', + :public_address => '10.10.10.10', + :port => '81', + :internal_address => '10.10.10.11', + :admin_address => '10.10.10.12' } + end + + it { should contain_keystone_endpoint('RegionOne/trove').with( + :ensure => 'present', + :public_url => "https://10.10.10.10:80/v1.0/\$(tenant_id)s", + :internal_url => "http://10.10.10.11:81/v1.0/\$(tenant_id)s", + :admin_url => "http://10.10.10.12:81/v1.0/\$(tenant_id)s" + ) } + end + + describe 'when overriding auth name' do + let :params do + { :password => 'foo', + :auth_name => 'trovey' } + end + + it { should contain_keystone_user('trovey') } + it { should contain_keystone_user_role('trovey@services') } + it { should contain_keystone_service('trovey') } + it { should contain_keystone_endpoint('RegionOne/trovey') } + end +end diff --git a/trove/spec/classes/trove_taskmanager_spec.rb b/trove/spec/classes/trove_taskmanager_spec.rb new file mode 100644 index 000000000..b38aae3e6 --- /dev/null +++ b/trove/spec/classes/trove_taskmanager_spec.rb @@ -0,0 +1,118 @@ +# +# Copyright (C) 2014 eNovance SAS +# +# Author: Emilien Macchi +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for trove::taskmanager +# +require 'spec_helper' + +describe 'trove::taskmanager' do + + shared_examples 'trove-taskmanager' do + + context 'with default parameters' do + + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete'}" + end + + it 'installs trove-taskmanager package and service' do + should contain_service('trove-taskmanager').with( + :name => platform_params[:taskmanager_service_name], + :ensure => 'running', + :hasstatus => true, + :enable => true + ) + should contain_package('trove-taskmanager').with( + :name => platform_params[:taskmanager_package_name], + :ensure => 'present', + :notify => 'Service[trove-taskmanager]' + ) + end + + it 'configures trove-taskmanager with default parameters' do + should contain_trove_taskmanager_config('DEFAULT/verbose').with_value(false) + should contain_trove_taskmanager_config('DEFAULT/debug').with_value(false) + should contain_trove_taskmanager_config('DEFAULT/nova_proxy_admin_user').with_value('admin') + should contain_trove_taskmanager_config('DEFAULT/nova_proxy_admin_pass').with_value('verysecrete') + should contain_trove_taskmanager_config('DEFAULT/nova_proxy_admin_tenant_name').with_value('admin') + end + + context 'when using a single RabbitMQ server' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_host => '10.0.0.1'}" + end + it 'configures trove-taskmanager with RabbitMQ' do + should contain_trove_taskmanager_config('DEFAULT/rabbit_host').with_value('10.0.0.1') + end + end + + context 'when using multiple RabbitMQ servers' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + rabbit_hosts => ['10.0.0.1','10.0.0.2']}" + end + it 'configures trove-taskmanager with RabbitMQ' do + should contain_trove_taskmanager_config('DEFAULT/rabbit_hosts').with_value(['10.0.0.1,10.0.0.2']) + end + end + + context 'when using MySQL' do + let :pre_condition do + "class { 'trove': + nova_proxy_admin_pass => 'verysecrete', + database_connection => 'mysql://trove:pass@10.0.0.1/trove'}" + end + it 'configures trove-taskmanager with RabbitMQ' do + should contain_trove_taskmanager_config('DEFAULT/sql_connection').with_value('mysql://trove:pass@10.0.0.1/trove') + end + end + end + end + + context 'on Debian platforms' do + let :facts do + { :osfamily => 'Debian', + :processorcount => 8 } + end + + let :platform_params do + { :taskmanager_package_name => 'trove-taskmanager', + :taskmanager_service_name => 'trove-taskmanager' } + end + + it_configures 'trove-taskmanager' + end + + context 'on RedHat platforms' do + let :facts do + { :osfamily => 'RedHat', + :processorcount => 8 } + end + + let :platform_params do + { :taskmanager_package_name => 'openstack-trove-taskmanager', + :taskmanager_service_name => 'openstack-trove-taskmanager' } + end + + it_configures 'trove-taskmanager' + end + +end diff --git a/trove/spec/shared_examples.rb b/trove/spec/shared_examples.rb new file mode 100644 index 000000000..8acb3eaef --- /dev/null +++ b/trove/spec/shared_examples.rb @@ -0,0 +1,56 @@ +shared_examples_for "a Puppet::Error" do |description| + it "with message matching #{description.inspect}" do + expect { should have_class_count(1) }.to raise_error(Puppet::Error, description) + end +end + +shared_examples 'generic trove service' do |service| + + context 'with default parameters' do + it 'installs package and service' do + should contain_package(service[:name]).with({ + :name => service[:package_name], + :ensure => 'present', + :notify => "Service[#{service[:name]}]" + }) + should contain_service(service[:name]).with({ + :name => service[:service_name], + :ensure => 'stopped', + :hasstatus => true, + :enable => false + }) + end + end + + context 'with overridden parameters' do + let :params do + { :enabled => true, + :ensure_package => '2014.1-1' } + end + + it 'installs package and service' do + should contain_package(service[:name]).with({ + :name => service[:package_name], + :ensure => '2014.1-1', + :notify => "Service[#{service[:name]}]" + }) + should contain_service(service[:name]).with({ + :name => service[:service_name], + :ensure => 'running', + :hasstatus => true, + :enable => true + }) + end + end + + context 'while not managing service state' do + let :params do + { :enabled => false, + :manage_service => false } + end + + it 'does not control service state' do + should contain_service(service[:name]).without_ensure + end + end +end diff --git a/trove/spec/spec_helper.rb b/trove/spec/spec_helper.rb new file mode 100644 index 000000000..53d4dd02d --- /dev/null +++ b/trove/spec/spec_helper.rb @@ -0,0 +1,7 @@ +require 'puppetlabs_spec_helper/module_spec_helper' +require 'shared_examples' + +RSpec.configure do |c| + c.alias_it_should_behave_like_to :it_configures, 'configures' + c.alias_it_should_behave_like_to :it_raises, 'raises' +end diff --git a/trove/spec/unit/provider/trove_config/ini_setting_spec.rb b/trove/spec/unit/provider/trove_config/ini_setting_spec.rb new file mode 100644 index 000000000..dc18f4638 --- /dev/null +++ b/trove/spec/unit/provider/trove_config/ini_setting_spec.rb @@ -0,0 +1,37 @@ +# these tests are a little concerning b/c they are hacking around the +# modulepath, so these tests will not catch issues that may eventually arise +# related to loading these plugins. +# I could not, for the life of me, figure out how to programatcally set the modulepath +$LOAD_PATH.push( + File.join( + File.dirname(__FILE__), + '..', + '..', + '..', + 'fixtures', + 'modules', + 'inifile', + 'lib') +) +require 'spec_helper' +provider_class = Puppet::Type.type(:trove_config).provider(:ini_setting) +describe provider_class do + + it 'should default to the default setting when no other one is specified' do + resource = Puppet::Type::Trove_config.new( + {:name => 'DEFAULT/foo', :value => 'bar'} + ) + provider = provider_class.new(resource) + provider.section.should == 'DEFAULT' + provider.setting.should == 'foo' + end + + it 'should allow setting to be set explicitly' do + resource = Puppet::Type::Trove_config.new( + {:name => 'dude/foo', :value => 'bar'} + ) + provider = provider_class.new(resource) + provider.section.should == 'dude' + provider.setting.should == 'foo' + end +end diff --git a/trove/spec/unit/provider/trove_datastore/trove_spec.rb b/trove/spec/unit/provider/trove_datastore/trove_spec.rb new file mode 100644 index 000000000..3c0590576 --- /dev/null +++ b/trove/spec/unit/provider/trove_datastore/trove_spec.rb @@ -0,0 +1,57 @@ +require 'puppet' +require 'spec_helper' +require 'puppet/provider/trove_datastore/trove' + +provider_class = Puppet::Type.type(:trove_datastore).provider(:trove) + +describe provider_class do + + let :datastore_name do + 'foo' + end + + let :resource do + Puppet::Type::Trove_datastore.new({ + :name => datastore_name, + :version => '0.1', + :ensure => 'present', + }) + end + + let :provider do + described_class.new(resource) + end + + before :each do + described_class.stubs(:list_trove_resources).with('datastore').returns([ + resource + ]) + end + + describe "self.instances" do + it "should have an instances method" do + provider.class.should respond_to(:instances) + end + + it "should list instances" do + datastores = described_class.instances + datastores.size.should == 1 + datastores.map {|provider| provider.name} == datastore_name + end + end + + describe '#create' do + it 'should call trove-manage' do + provider.expects(:trove_manage).with( + ['trove-manage', 'datastore_update', datastore_name, "''"] + ).returns(0) + + provider.expects(:trove_manage).with( + ['trove-manage', 'datastore_update', datastore_name, "0.1"] + ).returns(0) + + provider.create + end + end + +end diff --git a/trove/spec/unit/provider/trove_datastore_version/trove_spec.rb b/trove/spec/unit/provider/trove_datastore_version/trove_spec.rb new file mode 100644 index 000000000..3a2c6c29a --- /dev/null +++ b/trove/spec/unit/provider/trove_datastore_version/trove_spec.rb @@ -0,0 +1,50 @@ +require 'puppet' +require 'spec_helper' +require 'puppet/provider/trove_datastore_version/trove' + +provider_class = Puppet::Type.type(:trove_datastore_version).provider(:trove) + +describe provider_class do + + let :datastore_name do + 'foo' + end + + let :datastore_version do + '1.0' + end + + let :resource do + Puppet::Type::Trove_datastore_version.new({ + :name => datastore_version, + :ensure => 'present', + :datastore => datastore_name, + :manager => 'mysql', + :image_id => '1234', + :packages => 'mysql', + :active => 1 + }) + end + + let :provider do + described_class.new(resource) + end + + describe "self.instances" do + it "should have an instances method" do + provider.class.should respond_to(:instances) + end + end + + describe '#create' do + it 'should call trove-manage' do + provider.expects(:trove_manage).with( + ['trove-manage', 'datastore_version_update', datastore_name, "1.0", + 'mysql', '1234', 'mysql', '1'] + ).returns(0) + + provider.create + end + end + +end diff --git a/trove/spec/unit/provider/trove_spec.rb b/trove/spec/unit/provider/trove_spec.rb new file mode 100644 index 000000000..b38f3d8d5 --- /dev/null +++ b/trove/spec/unit/provider/trove_spec.rb @@ -0,0 +1,14 @@ +require 'puppet' +require 'spec_helper' +require 'puppet/provider/trove' + + +klass = Puppet::Provider::Trove + +describe Puppet::Provider::Trove do + + after :each do + klass.reset + end + +end diff --git a/trove/spec/unit/type/trove_config_spec.rb b/trove/spec/unit/type/trove_config_spec.rb new file mode 100644 index 000000000..71feea7c1 --- /dev/null +++ b/trove/spec/unit/type/trove_config_spec.rb @@ -0,0 +1,52 @@ +require 'puppet' +require 'puppet/type/trove_config' +describe 'Puppet::Type.type(:trove_config)' do + before :each do + @trove_config = Puppet::Type.type(:trove_config).new(:name => 'DEFAULT/foo', :value => 'bar') + end + + it 'should require a name' do + expect { + Puppet::Type.type(:trove_config).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + + it 'should not expect a name with whitespace' do + expect { + Puppet::Type.type(:trove_config).new(:name => 'f oo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should fail when there is no section' do + expect { + Puppet::Type.type(:trove_config).new(:name => 'foo') + }.to raise_error(Puppet::Error, /Parameter name failed/) + end + + it 'should not require a value when ensure is absent' do + Puppet::Type.type(:trove_config).new(:name => 'DEFAULT/foo', :ensure => :absent) + end + + it 'should accept a valid value' do + @trove_config[:value] = 'bar' + @trove_config[:value].should == 'bar' + end + + it 'should not accept a value with whitespace' do + @trove_config[:value] = 'b ar' + @trove_config[:value].should == 'b ar' + end + + it 'should accept valid ensure values' do + @trove_config[:ensure] = :present + @trove_config[:ensure].should == :present + @trove_config[:ensure] = :absent + @trove_config[:ensure].should == :absent + end + + it 'should not accept invalid ensure values' do + expect { + @trove_config[:ensure] = :latest + }.to raise_error(Puppet::Error, /Invalid value/) + end +end diff --git a/trove/templates/trove-guestagent.conf.erb b/trove/templates/trove-guestagent.conf.erb new file mode 100644 index 000000000..4188e0784 --- /dev/null +++ b/trove/templates/trove-guestagent.conf.erb @@ -0,0 +1,73 @@ +[DEFAULT] +# Show more verbose log output (sets INFO log level output) +verbose = <%= @verbose %> + +# Show debugging output in logs (sets DEBUG log level output) +debug = <%= @debug %> + +# Address to bind the API server +bind_host = 0.0.0.0 + +# Port the bind the API server to +bind_port = 8778 + +# AMQP Connection info +rabbit_user=<%= @rabbit_userid %> +rabbit_password=<%= @rabbit_password %> + +# Path to the extensions +api_extensions_path = trove/extensions/routes + +# Configuration options for talking to nova via the novaclient. +# These options are for an admin user in your keystone config. +# It proxies the token received from the user to send to nova via this admin users creds, +# basically acting like the client via that proxy token. +nova_proxy_admin_user = <%= @nova_proxy_admin_user %> +nova_proxy_admin_pass = <%= @nova_proxy_admin_pass %> +nova_proxy_admin_tenant_name = <%= @nova_proxy_admin_tenant_name %> +trove_auth_url = <%= @auth_url %> +swift_url = http://localhost:8080/v1/AUTH_ + +# Datastore management implementations. Format datastore:manager.impl +# datastore_registry_ext = mysql:trove.guestagent.datastore.mysql.manager.Manager, percona:trove.guestagent.datastore.mysql.manager.Manager + +# Root configuration +root_grant = ALL +root_grant_option = True + +#root_grant = ALTER ROUTINE, CREATE, ALTER, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, CREATE USER, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, PROCESS, REFERENCES, SELECT, SHOW DATABASES, SHOW VIEW, TRIGGER, UPDATE, USAGE +#root_grant_option = False + +# used by passlib to generate root password +#default_password_length = 36 + +# For communicating with trove-conductor +control_exchange = <%= @control_exchange %> + +# ============ kombu connection options ======================== + +rabbit_host=<%= @rabbit_host %> + +# ============ Logging information ============================= +log_dir = /tmp/ +log_file = logfile.txt + +# Users to ignore for user create/list/delete operations +ignore_users = os_admin +ignore_dbs = lost+found, mysql, information_schema + +# Strategy information for backups +backup_namespace = trove.guestagent.strategies.backup.mysql_impl +# Additional commandline options to be passed to the backup runner (by strategy). For example: +# backup_runner_options = InnoBackupEx:--no-lock, MySQLDump:--events --routines --triggers +restore_namespace = trove.guestagent.strategies.restore.mysql_impl +storage_strategy = SwiftStorage +storage_namespace = trove.guestagent.strategies.storage.swift +backup_swift_container = database_backups +backup_use_gzip_compression = True +backup_use_openssl_encryption = True +backup_aes_cbc_key = "default_aes_cbc_key" +backup_use_snet = False +backup_chunk_size = 65536 +backup_segment_max_size = 2147483648 + From d6c310d396193a3a73b22cdc3ccdd5fe19380e9a Mon Sep 17 00:00:00 2001 From: Ivan Chavero Date: Thu, 18 Dec 2014 08:27:49 -0700 Subject: [PATCH 6/6] Automatic update This module update commit was generated by Bade. For more info please check https://github.com/paramite/bade This commit is setting modules to following state: n1k-vsm - old commit: 69ff094069506f98431182c6097b3b6b9ea6fdb9 - new commit: 6ac71df4aa2bf806e35b83bd18ae9ea6b5605bc0 --- Puppetfile | 2 +- n1k-vsm/.gitignore | 4 + n1k-vsm/.gitreview | 4 + n1k-vsm/Gemfile | 12 + n1k-vsm/LICENSE | 175 +++++++++++++ n1k-vsm/Rakefile | 7 + n1k-vsm/files/n1kv | 5 + n1k-vsm/files/repackiso.py | 20 +- n1k-vsm/manifests/deploy.pp | 96 ++++--- n1k-vsm/manifests/init.pp | 124 ++++++--- n1k-vsm/manifests/pkgprep_ovscfg.pp | 375 ++++++++++++++-------------- n1k-vsm/manifests/vsmprep.pp | 218 +++++++++------- n1k-vsm/metadata.json | 28 +++ 13 files changed, 685 insertions(+), 385 deletions(-) create mode 100644 n1k-vsm/.gitignore create mode 100644 n1k-vsm/.gitreview create mode 100644 n1k-vsm/Gemfile create mode 100644 n1k-vsm/LICENSE create mode 100644 n1k-vsm/Rakefile create mode 100755 n1k-vsm/files/n1kv create mode 100644 n1k-vsm/metadata.json diff --git a/Puppetfile b/Puppetfile index d8870a394..1549bbab6 100644 --- a/Puppetfile +++ b/Puppetfile @@ -83,7 +83,7 @@ mod 'mysql', :git => 'https://github.com/puppetlabs/puppetlabs-mysql.git' mod 'n1k-vsm', - :commit => '69ff094069506f98431182c6097b3b6b9ea6fdb9', + :commit => '6ac71df4aa2bf806e35b83bd18ae9ea6b5605bc0', :git => 'https://github.com/stackforge/puppet-n1k-vsm.git' mod 'nagios', diff --git a/n1k-vsm/.gitignore b/n1k-vsm/.gitignore new file mode 100644 index 000000000..d4a93a066 --- /dev/null +++ b/n1k-vsm/.gitignore @@ -0,0 +1,4 @@ +*.swp +spec/fixtures/modules/* +pkg +Gemfile.lock diff --git a/n1k-vsm/.gitreview b/n1k-vsm/.gitreview new file mode 100644 index 000000000..c071db67b --- /dev/null +++ b/n1k-vsm/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=review.openstack.org +port=29418 +project=stackforge/puppet-n1k-vsm.git diff --git a/n1k-vsm/Gemfile b/n1k-vsm/Gemfile new file mode 100644 index 000000000..8de97162d --- /dev/null +++ b/n1k-vsm/Gemfile @@ -0,0 +1,12 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'puppetlabs_spec_helper', :require => false + gem 'puppet-lint', '~> 0.3.2' +end + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end diff --git a/n1k-vsm/LICENSE b/n1k-vsm/LICENSE new file mode 100644 index 000000000..67db85882 --- /dev/null +++ b/n1k-vsm/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/n1k-vsm/Rakefile b/n1k-vsm/Rakefile new file mode 100644 index 000000000..f01e55e20 --- /dev/null +++ b/n1k-vsm/Rakefile @@ -0,0 +1,7 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_parameter_defaults') +PuppetLint.configuration.send('disable_autoloader_layout') diff --git a/n1k-vsm/files/n1kv b/n1k-vsm/files/n1kv new file mode 100755 index 000000000..25c368b77 --- /dev/null +++ b/n1k-vsm/files/n1kv @@ -0,0 +1,5 @@ +#!/bin/sh + +/etc/init.d/network restart +systemctl start libvirtd.service + diff --git a/n1k-vsm/files/repackiso.py b/n1k-vsm/files/repackiso.py index f768fa835..317da1afc 100755 --- a/n1k-vsm/files/repackiso.py +++ b/n1k-vsm/files/repackiso.py @@ -1,6 +1,5 @@ #!/usr/bin/python -import shutil, tempfile, os, optparse, logging -import sys +import shutil, tempfile, os, optparse, logging, sys usage = "usage: %prog [options]" parser = optparse.OptionParser(usage=usage) @@ -71,6 +70,8 @@ def createOvfEnvXmlFile(domain, gateway, hostname, ip, subnet, password, vsm_mod st += ' \n' st += ' \n' % (password) st += ' \n' % (vsm_mode) + st += ' \n' + st += ' \n' #if vsm_mode == "primary": # st += ' \n' % (vsm_mode) #else: @@ -100,25 +101,24 @@ def main(): cret = Command('/bin/mount -o loop -t iso9660 %s %s' % (isoimg, mntdir)).run() #logger.info("%s %s" % (cret.output, cret.error)) if cret.failed: - print(sys.argv[0], "1 ", cret.output, cret.error) + print(sys.argv[0], "Error: Unable to mount disk ", cret.output, cret.error) sys.exit(1) cret = Command('/bin/cp -r %s/* %s' % (mntdir, ddir)).run() - print(sys.argv[0], "2 cwchang X", cret.output, "X", cret.error,"X") + print(sys.argv[0], "Copying files ", cret.output, "X", cret.error,"X") if cret.failed: - print(sys.argv[0], "2 ", cret.output, cret.error) + print(sys.argv[0], "Error: Unable to copy files ", cret.output, cret.error) sys.exit(1) #logger.info("%s %s" % (cret.output, cret.error)) cret = Command('/bin/umount %s' % (mntdir)).run() if cret.failed: - print(sys.argv[0], "3 ", cret.output, cret.error) + print(sys.argv[0], "Error: Unable to unmont dir ", cret.output, cret.error) sys.exit(1) #logger.info("%s %s" % (cret.output, cret.error)) - #logger.info("%s %s" % (cret.output, cret.error)) cret = Command('/bin/cp %s %s/ovf-env.xml' % (ovf_f.name, ddir)).run() if cret.failed: - print(sys.argv[0], "4 ", cret.output, cret.error) + print(sys.argv[0], "Error: Unable to copy ovf file ", cret.output, cret.error) sys.exit(1) #logger.info("%s %s" % (cret.output, cret.error)) @@ -126,13 +126,13 @@ def main(): if os.path.exists('%s/isolinux/isolinux.bin' % (ddir)): cret = Command('cd %s; /usr/bin/mkisofs -uid 0 -gid 0 -J -R -A Cisco_Nexus_1000V_VSM -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o %s .' % (ddir, repackediso)).run() if cret.failed: - print(sys.argv[0],"5 ", cret.output, cret.error) + print(sys.argv[0],"Error: Unable to create isofs ", cret.output, cret.error) sys.exit(1) #logger.info("%s %s" % (cret.output, cret.error)) else: cret = Command('cd %s; /usr/bin/mkisofs -uid 0 -gid 0 -J -R -A Cisco_Nexus_1000V_VSM -b boot/grub/iso9660_stage1_5 -no-emul-boot -boot-load-size 4 -boot-info-table -o %s .' % (ddir, repackediso)).run() if cret.failed: - print(sys.argv[0], "6 ", cret.output, cret.error) + print(sys.argv[0], "Error: Unable to create isofs grub ", cret.output, cret.error) sys.exit(1) #logger.info("%s %s" % (cret.output, cret.error)) diff --git a/n1k-vsm/manifests/deploy.pp b/n1k-vsm/manifests/deploy.pp index c07bc311c..02e88982f 100644 --- a/n1k-vsm/manifests/deploy.pp +++ b/n1k-vsm/manifests/deploy.pp @@ -1,76 +1,66 @@ -class n1k_vsm::deploy { - - #ensure tap interfaces and deploy the vsm - - $ctrltap = $n1k_vsm::ctrlinterface[0] - $ctrlmac = $n1k_vsm::ctrlinterface[1] - $ctrlbridge = $n1k_vsm::ctrlinterface[2] - $mgmttap = $n1k_vsm::mgmtinterface[0] - $mgmtmac = $n1k_vsm::mgmtinterface[1] - $mgmtbridge = $n1k_vsm::mgmtinterface[2] - $pkttap = $n1k_vsm::pktinterface[0] - $pktmac = $n1k_vsm::pktinterface[1] - $pktbridge = $n1k_vsm::pktinterface[2] - -# tapint {"$ctrltap": -# bridge => $ctrlbridge, -# ensure => present -# } +# == Class: n1k_vsm::deploy +# +# This class that actually deploys a VSM VM in the server +# +# == Parameters: # -# tapint {"$mgmttap": -# bridge => $mgmtbridge, -# ensure => present -# } +# == Actions: # -# tapint {"$pkttap": -# bridge => $pktbridge, -# ensure => present -# } +# == Requires: +# +# This depends of n1kv_vsm class to set some environmental variables +# +# == Sample Usage: +# +class n1k_vsm::deploy +{ + #ensure tap interfaces and deploy the vsm + $ctrltap = 'vsm-ctrl0' + $mgmttap = 'vsm-mgmt0' + $pkttap = 'vsm-pkt0' - - $diskfile = "/var/spool/vsm/${n1k_vsm::role}_disk" + #$diskfile = "/var/spool/vsm/${n1k_vsm::vsm_role}_disk" - exec { "Exec_create_disk": - command => "/usr/bin/qemu-img create -f raw $diskfile ${n1k_vsm::disksize}G", - unless => "/usr/bin/virsh list | grep -c ' ${n1k_vsm::vsmname} .* running'", + exec { 'Exec_create_disk': + command => "/usr/bin/qemu-img create -f raw ${n1k_vsm::diskfile} ${n1k_vsm::disksize}G", + unless => "/usr/bin/virsh list | grep -c ' ${n1k_vsm::vsmname} .* running'", } -> - exec {"Debug_Exec_create_disk_debug": - command => "${n1k_vsm::Debug_Print} \"[INFO]\nExec_create_disk /usr/bin/qemu-img create -f raw $diskfile ${n1k_vsm::disksize}G\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_Exec_create_disk_debug': + command => "${n1k_vsm::Debug_Print} \"[INFO]\nExec_create_disk /usr/bin/qemu-img create -f raw ${n1k_vsm::diskfile} ${n1k_vsm::disksize}G\" >> ${n1k_vsm::Debug_Log}", } - $targetxmlfile = "/var/spool/vsm/vsm_${n1k_vsm::role}_deploy.xml" - file { "File_Target_XML_File": - path => "$targetxmlfile", - owner => 'root', - group => 'root', - mode => '666', + $targetxmlfile = "/var/spool/vsm/vsm_${n1k_vsm::vsm_role}_deploy.xml" + file { 'File_Target_XML_File': + path => $targetxmlfile, + owner => 'root', + group => 'root', + mode => '0666', content => template('n1k_vsm/vsm_vm.xml.erb'), - require => Exec["Exec_create_disk"], + require => Exec['Exec_create_disk'], } -> - exec {"Debug_File_Target_XML_FILE": - command => "${n1k_vsm::Debug_Print} \"[INFO]\nFile_Target_XML_File\n path=$targetxmlfile \n owner=root \n group=root \n mode=666 \n\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_File_Target_XML_FILE': + command => "${n1k_vsm::Debug_Print} \"[INFO]\nFile_Target_XML_File\n path=${targetxmlfile} \n owner=root \n group=root \n mode=666 \n\" >> ${n1k_vsm::Debug_Log}", } - exec { "Exec_Create_VSM": - command => "/usr/bin/virsh define $targetxmlfile", - unless => "/usr/bin/virsh list | grep -c ' ${n1k_vsm::vsmname} .* running'", + exec { 'Exec_Create_VSM': + command => "/usr/bin/virsh define ${targetxmlfile} && /usr/bin/virsh autostart ${n1k_vsm::vsmname}", + unless => "/usr/bin/virsh list | grep -c ' ${n1k_vsm::vsmname} '", } -> - exec {"Debug_Exec_Create_VSM": - command => "${n1k_vsm::Debug_Print} \"[INFO]\nExec_Launch_VSM \n command=/bin/echo /usr/bin/virsh define $targetxmlfile \n unless=/usr/bin/virsh list --all | grep -c ' ${n1k_vsm::vsmname} ' \" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_Exec_Create_VSM': + command => "${n1k_vsm::Debug_Print} \"[INFO]\nExec_Launch_VSM \n command=/bin/echo /usr/bin/virsh define ${targetxmlfile} \n unless=/usr/bin/virsh list --all | grep -c ' ${n1k_vsm::vsmname} ' \" >> ${n1k_vsm::Debug_Log}", } - exec { "Exec_Launch_VSM": - command => "/usr/bin/virsh start ${n1k_vsm::vsmname}", - unless => "/usr/bin/virsh list --all | grep -c ' ${n1k_vsm::vsmname} .* running '", + exec { 'Exec_Launch_VSM': + command => "/usr/bin/virsh start ${n1k_vsm::vsmname}", + unless => "/usr/bin/virsh list --all | grep -c ' ${n1k_vsm::vsmname} .* running '", } -> - exec {"Debug_Exec_Launch_VSM": + exec { 'Debug_Exec_Launch_VSM': command => "${n1k_vsm::Debug_Print} \"[INFO]\nExec_Launch_VSM \n command=/bin/echo /usr/bin/virsh start ${n1k_vsm::vsmname} \n unless=/usr/bin/virsh list --all | grep -c ' ${n1k_vsm::vsmname} .* running' \" >> ${n1k_vsm::Debug_Log}", } - Exec["Exec_create_disk"] -> File["File_Target_XML_File"] -> Exec["Exec_Create_VSM"] -> Exec["Exec_Launch_VSM"] + Exec['Exec_create_disk'] -> File['File_Target_XML_File'] -> Exec['Exec_Create_VSM'] -> Exec['Exec_Launch_VSM'] } - diff --git a/n1k-vsm/manifests/init.pp b/n1k-vsm/manifests/init.pp index b546f9644..5a0302af3 100644 --- a/n1k-vsm/manifests/init.pp +++ b/n1k-vsm/manifests/init.pp @@ -1,46 +1,102 @@ +# == Class: n1k_vsm +# +# This class deploys a Nexus1000v VSM VEM in a server +# +# == Parameters: +# +# [*phy_if_bridge*] - Physical interface used for the bridge to connect outside the node +# +# [*phy_gateway*] - IP address of the default gateway for the external interface +# +# [*vsm_role*] - Role (primary/secondary) of the Nexus1000v VSM +# +# [*vsm_domain_id*] - Domain id of the Nexus1000v VSM +# +# [*vsm_admin_passwd*] - Password of admin user on the Nexus1000v VSM +# +# [*vsm_mgmt_ip*] - IP of the management interface on the Nexus1000v VSM +# +# [*vsm_mgmt_netmask*] - IP netmask of the management interface of the Nexus1000v VSM +# +# [*vsm_mgmt_gateway*] - IP of the default gateway for the management interface of the Nexus1000v VSM +# +# [*n1kv_source*] - Location where to get the Nexus1000v VSM ISO package +# +# [*n1kv_version*] - Version of the Nexus1000v VSM +# +# == Actions: +# +# == Requires: +# +# == Sample Usage: +# class n1k_vsm( - $configureovs = false, - $ovsbridge, - $physicalinterfaceforovs = 'enp1s0f0', - $nodeip, - $nodenetmask, - $nodegateway, - $vsmname, - $consolepts = 2, - $role = 'primary', - $domainid, - $adminpasswd, - $mgmtip, - $mgmtnetmask, - $mgmtgateway, - $ctrlinterface, - $mgmtinterface, - $pktinterface, - $memory = 4096000, - $vcpu = 2, - $disksize = 4, - $n1kv_source = "puppet:///modules/n1k_vsm/vsm.iso", - $n1kv_version = "latest", - ) -{ - - $imgfile = "/var/spool/vsm/${role}_repacked.iso" - $diskfile = "/var/spool/vsm/${role}_disk" - - $Debug_Print = "/usr/bin/printf" - $Debug_Log = "/tmp/n1kv_vsm_puppet.log" + $phy_if_bridge = 'enp1s0f0', + $phy_gateway, + $vsm_role = 'primary', + $vsm_domain_id, + $vsm_admin_passwd, + $vsm_mgmt_ip, + $vsm_mgmt_netmask, + $vsm_mgmt_gateway, + $n1kv_source = 'puppet:///modules/n1k_vsm/vsm.iso', + $n1kv_version = 'latest' +) { + # + # Network parameters + # + $ovsbridge = 'br-int' + $phy_ip_addr = inline_template("<%= scope.lookupvar('::ipaddress_${n1k_vsm::phy_if_bridge}') %>") + $phy_ip_mask = inline_template("<%= scope.lookupvar('::netmask_${n1k_vsm::phy_if_bridge}') %>") + #$gw_intf = inline_template("<%= scope.lookupvar('::gateway_device') %>") + $gw_intf = $n1k_vsm::phy_gateway + + # + # VSM parameters + # + if $n1k_vsm::vsm_role == 'primary' { + $vsmname = 'vsm-p' + $mgmtip = $vsm_mgmt_ip + $mgmtnetmask = $vsm_mgmt_netmask + $mgmtgateway = $vsm_mgmt_gateway + } else { # secondary + $vsmname = 'vsm-s' + $mgmtip = '0.0.0.0' + $mgmtnetmask = '0.0.0.0' + $mgmtgateway = '0.0.0.0' + } + $consolepts = 2 + $memory = 4096000 + $vcpu = 2 + $disksize = 4 + $imgfile = "/var/spool/vsm/${n1k_vsm::vsm_role}_repacked.iso" + $diskfile = "/var/spool/vsm/${n1k_vsm::vsm_role}_disk" + + + $Debug_Print = '/usr/bin/printf' + $Debug_Log = '/tmp/n1kv_vsm_puppet.log' + + notify {"Arg: intf ${phy_if_bridge} vsm_role ${vsm_role} domainid ${vsm_domain_id}" : withpath => true} + notify {"ip ${phy_ip_addr} mask ${phy_ip_mask} gw ${n1k_vsm::phy_gateway}" : withpath => true} + notify {"gw_dv ${gw_intf} ovs ${ovsbridge} vsmname ${n1k_vsm::vsmname}" : withpath => true} + notify {"mgmtip ${n1k_vsm::mgmtip} vsm_mask ${n1k_vsm::mgmtnetmask} vsm_gw ${n1k_vsm::mgmtgateway}": withpath => false} + # # Clean up debug log # - file {"File_$Debug_Log": - path => $Debug_Log, - ensure => "absent", + file {"File_${Debug_Log}": + ensure => 'absent', + path => $Debug_Log, +# } -> +# file_line { "Adding info to debug": +# path => $Debug_Log, +# line => "phy ${n1k_vsm::phy_if_bridge} ip ${n1k_vsm::phy_ip_addr} gw ${n1k_vsm:phy_gateway}", } include n1k_vsm::pkgprep_ovscfg include n1k_vsm::vsmprep include n1k_vsm::deploy - File["File_$Debug_Log"] -> Class['n1k_vsm::pkgprep_ovscfg'] -> Class['n1k_vsm::vsmprep'] -> Class['n1k_vsm::deploy'] + File["File_${Debug_Log}"] -> Class['n1k_vsm::pkgprep_ovscfg'] -> Class['n1k_vsm::vsmprep'] -> Class['n1k_vsm::deploy'] } diff --git a/n1k-vsm/manifests/pkgprep_ovscfg.pp b/n1k-vsm/manifests/pkgprep_ovscfg.pp index 9ee8cb925..0abc62784 100644 --- a/n1k-vsm/manifests/pkgprep_ovscfg.pp +++ b/n1k-vsm/manifests/pkgprep_ovscfg.pp @@ -1,264 +1,253 @@ -class n1k_vsm::pkgprep_ovscfg { +# == Class: n1k_vsm::pkgprep_ovscfg +# +# This class prepares the packages and ovs bridge for the VSM VM +# +# == Parameters: +# +# None +# +# == Actions: +# +# == Requires: +# +# This requires n1k_vsm class to set some environmental variables +# +# == Sample Usage: +# +class n1k_vsm::pkgprep_ovscfg +{ + require n1k_vsm + include n1k_vsm # Definition of sync points - - $Sync_Point_KVM = "##SYNC_POINT_KVM" - $Sync_Point_Virsh_Network = "##SYNC_POINT_VIRSH_NETWORK" - case "$::osfamily" { - "RedHat": { + $Sync_Point_KVM = '##SYNC_POINT_KVM' + $Sync_Point_Virsh_Network = '##SYNC_POINT_VIRSH_NETWORK' + + case $::osfamily { + 'RedHat': { # - # Order indepedent resources + # Order indepedent resources # - service {"Service_network": - name => "network", - ensure => "running", - restart => "/sbin/service network restart || /bin/true", + service { 'Service_network': + ensure => running, + name => 'network', + restart => '/sbin/service network restart || /bin/true', } -> - exec {"Debug_Service_network": + exec { 'Debug_Service_network': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Service_network\n name=network\n ensure=running\n enable=true\n restart=/sbin/service network restart\n\" >> ${n1k_vsm::Debug_Log}", } + + # # VSM dependent packages installation section # - # Eng note - # cwchang: Ideally we should have either of this logic - # 1. Have an iteration thru the package list in the $pkgs.each ... - # Somehow this syntax needs to turn on future parser by document - # 2. package resource should be able to run a name list - # Neither one works. We go for rudimentary one-by-one here for now. - # Pitfalls observed: - # 1. We cannot reassign variables for some reason - # 2. We cannot leave spaces in name - # qemu-kvm-rhev - package {"Package_qemu-kvm": - name => "qemu-kvm", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], + package { 'Package_qemu-kvm': + ensure => installed, + name => 'qemu-kvm', + before => Notify[ $Sync_Point_KVM ], } -> - exec {"Debug_Package_qemu-kvm": + exec { 'Debug_Package_qemu-kvm': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_qemu-kvm \n name=qemu-kvm \n ensure=installed\n\" >> ${n1k_vsm::Debug_Log}", } - package {"Package_virt-viewer": - name => "virt-viewer", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], - } - -> - exec {"Debug_Package_virt-viewer": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_virt-viewer \n name=virt-viewer \n ensure=installed \n\" >> ${n1k_vsm::Debug_Log}", - } - - package {"Package_virt-manager": - name => "virt-manager", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], - } - -> - exec {"Debug_Package_virt-manager": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_virt-manager \n name=virt-manager \n ensure=installed\n\" >> ${n1k_vsm::Debug_Log}", - } - - package {"Package_libvirt": - name => "libvirt", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], + package {'Package_libvirt': + ensure => installed, + name => 'libvirt', + before => Notify[ $Sync_Point_KVM ], } -> - exec {"Debug_Package_libvirt": + exec { 'Debug_Package_libvirt': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_libvirt \n name=libvirt \n ensure=installed\n\" >> ${n1k_vsm::Debug_Log}", } - - package {"Package_libvirt-python": - name => "libvirt-python", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], + + package { 'Package_libvirt-python': + ensure => installed, + name => 'libvirt-python', + before => Notify[ $Sync_Point_KVM ], } -> - exec {"Debug_Package_libvirt-python": + exec { 'Debug_Package_libvirt-python': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_libvirt-python \n name=libvirt-python \n ensure=installed\n\" >> ${n1k_vsm::Debug_Log}", } - - #package {"Package_python-virtinst": - # name => "python-virtinst", - # ensure => "installed", - # before => Notify["$Sync_Point_KVM"], - #} - #-> - #exec {"Debug_Package_python-virtinst": - # command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_python-virtinst \n name=python-virtinst \n ensure=installed \n\" >> ${n1k_vsm::Debug_Log}", - #} - - #package {"Package_genisoimage": - # name => "genisoimage", - # ensure => "installed", - # before => Notify["$Sync_Point_KVM"], - #} - #-> - #exec {"Debug_Package_genisoimage": - # command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_genisoimage \n name=genisoimage \n ensure=installed \n\" >> ${n1k_vsm::Debug_Log}", - #} - package {"Package_ebtables": - name => "ebtables", - #ensure => "purged", - ensure => "installed", - before => Notify["$Sync_Point_KVM"], + package { 'Package_ebtables': + ensure => installed, + name => 'ebtables', + before => Notify[ $Sync_Point_KVM ], } -> - exec {"Debug_Package_ebtables": + exec { 'Debug_Package_ebtables': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_ebtables \n name=ebtables \n ensure=purged \n\" >> ${n1k_vsm::Debug_Log}", } - notify{"$Sync_Point_KVM":} + notify { $Sync_Point_KVM :} - service {"Service_libvirtd": - name => "libvirtd", - ensure => "running", + service { 'Service_libvirtd': + ensure => running, + name => 'libvirtd', } -> - exec {"Debug_Service_libvirtd": + exec { 'Debug_Service_libvirtd': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Service_libvirtd\n name=libvirtd \n ensure=running \n\" >> ${n1k_vsm::Debug_Log}", } - + # - # Virsh network exec configuration section + # Virsh network exec configuration section # - exec {"Exec_removenet": - command => "/usr/bin/virsh net-destroy default || /bin/true", - unless => "/usr/bin/virsh net-info default | /bin/grep -c 'Active: .* no'", - before => Notify["$Sync_Point_Virsh_Network"], + exec { 'Exec_removenet': + command => '/usr/bin/virsh net-destroy default || /bin/true', + unless => '/usr/bin/virsh net-info default | /bin/grep -c \'Active: .* no\'', + before => Notify[ $Sync_Point_Virsh_Network ], } -> - exec {"Debug_Exec_removenet": + exec { 'Debug_Exec_removenet': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_removenet \n command=/usr/bin/virsh net-destroy default || /bin/true \n unless=/usr/bin/virsh net-info default | /bin/grep -c 'Active: .* no'\n\" >> ${n1k_vsm::Debug_Log}", } - exec {"Exec_disableautostart": - command => "/usr/bin/virsh net-autostart --disable default || /bin/true", - unless => "/usr/bin/virsh net-info default | /bin/grep -c 'Autostart: .* no'", - before => Notify["$Sync_Point_Virsh_Network"], + exec { 'Exec_disableautostart': + command => '/usr/bin/virsh net-autostart --disable default || /bin/true', + unless => '/usr/bin/virsh net-info default | /bin/grep -c \'Autostart: .* no\'', + before => Notify[ $Sync_Point_Virsh_Network ], } -> - exec {"Debug_Exec_disableautostart": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_disableautostart' \n command=/usr/bin/virsh net-autostart --disable default || /bin/true \n unless /usr/bin/virsh net-info default | grep -c 'Autostart: .* no'\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_Exec_disableautostart': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_disableautostart \n command=/usr/bin/virsh net-autostart --disable default || /bin/true \n unless /usr/bin/virsh net-info default | grep -c 'Autostart: .* no'\" >> ${n1k_vsm::Debug_Log}", } - - notify{"$Sync_Point_Virsh_Network":} - package {"Package_openvswitch": - name => "openvswitch", - ensure => "installed", + notify{ $Sync_Point_Virsh_Network :} + + package { 'Package_openvswitch': + ensure => installed, + name => 'openvswitch', } -> - exec {"Debug_Package_openvswitch": + exec { 'Debug_Package_openvswitch': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Package_openvswitch \n name=openvswitch \n ensure=installed\n\" >> ${n1k_vsm::Debug_Log}", } - # - # bring up OVS and perform interface configuration - # - service {"Service_openvswitch": - name => "openvswitch", - ensure => "running", - enable => "true", + # + # bring up OVS and perform interface configuration + # + service { 'Service_openvswitch': + ensure => running, + name => 'openvswitch', + enable => true, } -> - exec {"Debug_Service_openvswitch": + exec { 'Debug_Service_openvswitch': command => "${n1k_vsm::Debug_Print} \"[INFO]\n Service_openvswitch \n name=openvswitch \n ensure=running \n enable=true\n\" >> ${n1k_vsm::Debug_Log}", } - - exec {"Exec_AddOvsBr": - command => "/usr/bin/ovs-vsctl -- --may-exist add-br $n1k_vsm::ovsbridge", - } - -> - exec {"Debug_Exec_AddOvsBr": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_AddOvsBr \n command=/usr/bin/ovs-vsctl -- --may-exist add-br $n1k_vsm::ovsbridge \n \" >> ${n1k_vsm::Debug_Log}", - } +# exec { 'Exec_AddOvsBr': +# command => "/usr/bin/ovs-vsctl -- --may-exist add-br ${n1k_vsm::ovsbridge}", +# } +# -> +# exec { 'Debug_Exec_AddOvsBr': +# command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_AddOvsBr \n command=/usr/bin/ovs-vsctl -- --may-exist add-br ${n1k_vsm::ovsbridge} \n \" >> ${n1k_vsm::Debug_Log}", +# } - # - # Modify Ovs bridge inteface configuation file - # - augeas {"Augeas_modify_ifcfg-ovsbridge": - name => "$n1k_vsm::ovsbridge", - context => "/files/etc/sysconfig/network-scripts/ifcfg-$n1k_vsm::ovsbridge", - changes => [ - "set DEVICE $n1k_vsm::ovsbridge", - "set BOOTPROTO none", - "set IPADDR $n1k_vsm::nodeip", - "set NETMASK $n1k_vsm::nodenetmask", - "set ONBOOT yes", - "set TYPE OVSBridge", - "set DEVICETYPE ovs", - ], - notify => Service["Service_network"], - } - -> - exec {"Debug_Augeas_modify_ifcfg-ovsbridge": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Augeas_modify_ifcfg-$n1k_vsm::ovsbridge \n name=$n1k_vsm::ovsbridge \n context=/files/etc/sysconfig/network-scripts/ifcfg-$n1k_vsm::ovsbridge \n\" >> ${n1k_vsm::Debug_Log}", - } + notify { "Debug br ${n1k_vsm::ovsbridge} intf ${n1k_vsm::phy_if_bridge} ." : withpath => true } + notify { "Debug ${n1k_vsm::vsmname} ip ${n1k_vsm::phy_ip_addr} mask ${n1k_vsm::phy_ip_mask} gw_intf ${n1k_vsm::gw_intf}" : withpath => true } - # - # Modify Physical Interface config file - # - augeas {"Augeas_modify_ifcfg-physicalinterfaceforovs": - name => "$n1k_vsm::physicalinterfaceforovs", - context => "/files/etc/sysconfig/network-scripts/ifcfg-$n1k_vsm::physicalinterfaceforovs", - changes => [ - "set ONBOOT yes", - "set BOOTPROTO none", - "set TYPE OVSPort", - "set DEVICETYPE ovs", - "set OVS_BRIDGE $n1k_vsm::ovsbridge", - "rm IPADDR", - "rm NETMASK", - ], - } - -> - exec {"Debug_Augeas_modify_ifcfg-physicalinterfaceforovs": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Augeas_modify_ifcfg-physicalinterfaceforovs \n name=$n1k_vsm::physicalinterfaceforovs \n context=/files/etc/sysconfig/network-scripts/ifcfg-$n1k_vsm::physicalinterfaceforovs\n\" >> ${n1k_vsm::Debug_Log}", - } + # Check if we've already configured the ovs + if $n1k_vsm::gw_intf != $n1k_vsm::ovsbridge { + # + # Modify Ovs bridge inteface configuation file + # + augeas { 'Augeas_modify_ifcfg-ovsbridge': + name => $n1k_vsm::ovsbridge, + context => "/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::ovsbridge}", + changes => [ + 'set TYPE OVSBridge', + "set DEVICE ${n1k_vsm::ovsbridge}", + 'set DEVICETYPE ovs', + "set OVSREQUIRES ${n1k_vsm::ovsbridge}", + 'set NM_CONTROLLED no', + 'set BOOTPROTO none', + 'set ONBOOT yes', + 'set DEFROUTE yes', + 'set MTU 1500', + "set NAME ${n1k_vsm::ovsbridge}", + "set IPADDR ${n1k_vsm::phy_ip_addr}", + "set NETMASK ${n1k_vsm::phy_ip_mask}", + "set GATEWAY ${n1k_vsm::phy_gateway}", + 'set USERCTL no', + ], + #notify => Service["Service_network"], + } + -> + exec { 'Debug_Augeas_modify_ifcfg-ovsbridge': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Augeas_modify_ifcfg-${n1k_vsm::ovsbridge} \n name=${n1k_vsm::ovsbridge} \n context=/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::ovsbridge} \n\" >> ${n1k_vsm::Debug_Log}", + } - $intf=$n1k_vsm::physicalinterfaceforovs - $phy_bridge="/tmp/phy_bridge" - # - # Move physical port around from host bridge if any, to ovs bridge - # - #exec {"Exec_phy_bridge": - # command => "/usr/sbin/brctl show | /bin/grep $intf | /bin/sed 's/[\t ].*//' > $phy_bridge", - #} - #-> - #exec {"Debug_Exec_phy_bridge": - # command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_phy_bridge \n /usr/sbin/brctl show | /bin/grep $intf | /bin/sed 's/[\t ].*//' > $phy_bridge \n \" >> ${n1k_vsm::Debug_Log}", - #} - - exec {"Exec_rebridge": - #command => "/usr/bin/test -s $phy_bridge && /usr/sbin/brctl delif \$(cat $phy_bridge) $intf || /bin/true; /usr/bin/ovs-vsctl -- --may-exist add-port $n1k_vsm::ovsbridge $intf", - command => "/usr/bin/ovs-vsctl -- --may-exist add-port $n1k_vsm::ovsbridge $intf", - #notify => Service["Service_network"], - } - -> - exec {"Debug_Exec_rebridge": - #command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_rebridge \n /usr/bin/test -s $phy_bridge && /usr/sbin/brctl delif \$(cat $phy_bridge) $intf || /bin/true; /usr/bin/ovs-vsctl -- --may-exist add-port $n1k_vsm::ovsbridge $intf; /bin/rm -f $phy_bridge \n\" >> ${n1k_vsm::Debug_Log}", - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_rebridge \n /usr/bin/ovs-vsctl -- --may-exist add-port $n1k_vsm::ovsbridge $intf \n\" >> ${n1k_vsm::Debug_Log}", - } + # + # Modify Physical Interface config file + # + augeas { 'Augeas_modify_ifcfg-phy_if_bridge': + name => $n1k_vsm::phy_if_bridge, + context => "/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::phy_if_bridge}", + changes => [ + 'set TYPE OVSPort', + "set DEVICE ${n1k_vsm::phy_if_bridge}", + 'set DEVICETYPE ovs', + "set OVS_BRIDGE ${n1k_vsm::ovsbridge}", + 'set NM_CONTROLLED no', + 'set BOOTPROTO none', + 'set ONBOOT yes', + "set NAME ${n1k_vsm::phy_if_bridge}", + 'rm IPADDR', + 'rm NETMASK', + 'rm GATEWAY', + 'set USERCTL no', + ], + notify => Service['Service_network'], + } +# -> +# exec { 'Add default route': +# command => "/sbin/route add default gw ${n1k_vsm::phy_gw_ip} ${n1k_vsm::ovsbridge}", +# } + -> + exec { 'Debug_Augeas_modify_ifcfg-phy_if_bridge': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Augeas_modify_ifcfg-phy_if_bridge \n name=${n1k_vsm::phy_if_bridge} \n context=/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::phy_if_bridge}\n\" >> ${n1k_vsm::Debug_Log}", + } + # + # Make sure that networking comes fine after reboot + # + file { 'Create_Init_File': + replace => 'yes', + path => '/etc/init.d/n1kv', + owner => 'root', + group => 'root', + mode => '0775', + source => 'puppet:///modules/n1k_vsm/n1kv', +# content => '#!/bin/sh \n\n/etc/init.d/network restart \n/usr/lib/systemd/system/libvirtd.service restart \n\n', + } + -> + exec { 'Debug_File_Init': + command => '/usr/bin/ln -s /etc/init.d/n1kv /etc/rc.d/rc3.d/S98n1kv', + } + } # endif of if "${n1k_vsm::gw_intf}" != "${n1k_vsm::ovsbridge}" # # Order enforcement logic - # - #Notify["$Sync_Point_KVM"] -> Service["Service_libvirtd"] -> Notify["$Sync_Point_Virsh_Network"] -> Package["Package_openvswitch"] -> Service["Service_openvswitch"] -> Exec["Exec_AddOvsBr"]->Augeas["Augeas_modify_ifcfg-ovsbridge"]->Augeas["Augeas_modify_ifcfg-physicalinterfaceforovs"]->Exec["Exec_phy_bridge"]->Exec["Exec_rebridge"] - Notify["$Sync_Point_KVM"] -> Service["Service_libvirtd"] -> Notify["$Sync_Point_Virsh_Network"] -> Package["Package_openvswitch"] -> Service["Service_openvswitch"] -> Exec["Exec_AddOvsBr"]->Augeas["Augeas_modify_ifcfg-ovsbridge"]->Augeas["Augeas_modify_ifcfg-physicalinterfaceforovs"]->Exec["Exec_rebridge"] + # + if $n1k_vsm::gw_intf != $n1k_vsm::ovsbridge { + Notify[$Sync_Point_KVM]->Service['Service_libvirtd']->Notify[$Sync_Point_Virsh_Network]->Package['Package_openvswitch']->Service['Service_openvswitch']->Augeas['Augeas_modify_ifcfg-ovsbridge']->Augeas['Augeas_modify_ifcfg-phy_if_bridge']->File['Create_Init_File'] +#->Exec["Exec_rebridge"] + } else { + Notify[$Sync_Point_KVM]->Service['Service_libvirtd']->Notify[$Sync_Point_Virsh_Network]->Package['Package_openvswitch']->Service['Service_openvswitch'] + } } - "Ubuntu": { + 'Ubuntu': { } default: { # # bail out for unsupported OS # - fail(": os[$os] is not supported") + fail(": os[${::os}] is not supported") } } } + diff --git a/n1k-vsm/manifests/vsmprep.pp b/n1k-vsm/manifests/vsmprep.pp index 4c9ae8695..4d6470456 100644 --- a/n1k-vsm/manifests/vsmprep.pp +++ b/n1k-vsm/manifests/vsmprep.pp @@ -1,162 +1,192 @@ -class n1k_vsm::vsmprep { +# == Class: n1k_vsm::vsmprep +# +# This class prepares the VSM image to be deploy in a server +# +# == Parameters: +# +# None +# +# == Actions: +# +# == Requires: +# +# This class requires n1kv_vsm to set some environmental variables +# +# == Sample Usage: +# +class n1k_vsm::vsmprep +{ include 'stdlib' - + require n1k_vsm + include n1k_vsm + # # VSM package source parsing logic # $source = $n1k_vsm::n1kv_source - $source_method = regsubst($source, "^(.+):.*", '\1') + $sourcemethod = regsubst($source, '^(.+):.*', '\1') $dest = inline_template('<%= File.basename(source) %>') - $VSM_Bin_Prepare_Sync_Point="##VSM_BIN_PREPARE_SYNC_POINT" - $VSM_Spool_Dir="/var/spool/vsm" - $VSM_RPM_Install_Dir="/opt/cisco/vsm" - $VSM_Repackage_Script_Name="repackiso.py" - $VSM_Repackage_Script="/tmp/$VSM_Repackage_Script_Name" - $VSM_DEST="$VSM_Spool_Dir/$dest" - $VSM_PKG_NAME="nexus-1000v-vsm" - $VSM_ISO="vsm.iso" + $VSM_Bin_Prepare_Sync_Point='##VSM_BIN_PREPARE_SYNC_POINT' + $VSM_Spool_Dir='/var/spool/cisco/vsm' + $VSM_RPM_Install_Dir='/opt/cisco/vsm' + $VSM_Repackage_Script_Name='repackiso.py' + $VSM_Repackage_Script="/tmp/${VSM_Repackage_Script_Name}" + $VSM_DEST="${VSM_Spool_Dir}/${dest}" + $VSM_PKG_NAME='nexus-1000v-vsm' + $VSM_ISO='vsm.iso' # - # prepare vsm spool folder + # prepare vsm folders # - file {"File_VSM_Spool_Dir": - path => "$VSM_Spool_Dir", - ensure => "directory", - owner => "root", - group => "root", - mode => "664", + file { 'File_VSM_Spool_Dir': + ensure => directory, + path => $VSM_Spool_Dir, + owner => 'root', + group => 'root', + mode => '0664', } -> - exec {"Debug_File_VSM_Spool_Dir": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n File_VSM_Spool_Dir\n path=$VSM_Spool_Dir \n ensure=directory \n owner=root \n group=root \n mode=664 \n\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_File_VSM_Spool_Dir': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n File_VSM_Spool_Dir\n path=${VSM_Spool_Dir} \n ensure=directory \n owner=root \n group=root \n mode=664 \n\" >> ${n1k_vsm::Debug_Log}", } + file { 'File_VSM_RPM_Dir': + ensure => directory, + path => $VSM_RPM_Install_Dir, + owner => 'root', + group => 'root', + mode => '0664', + } + -> + exec { 'Debug_File_VSM_RPM_Dir': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n File_VSM_RPM_Install_Dir\n path=${VSM_RPM_Install_Dir} \n ensure=directory \n owner=root \n group=root \n mode=664 \n\" >> ${n1k_vsm::Debug_Log}", + } - case "$source_method" { - "http": { - yumrepo {"http-cisco-foreman": - baseurl => "$n1k_vsm::n1kv_source", - descr => "Internal repo for Foreman", - enabled => "1", - gpgcheck => "1", - proxy => "_none_", - gpgkey => "${n1k_vsm::n1kv_source}/RPM-GPG-KEY", + case $sourcemethod { + http: { + yumrepo { 'http-cisco-foreman': + baseurl => $n1k_vsm::n1kv_source, + descr => 'Internal repo for Foreman', + enabled => 1, + gpgcheck => 1, + proxy => '_none_', + gpgkey => "${n1k_vsm::n1kv_source}/RPM-GPG-KEY", } -> - package {"Package_VSM": - name => "$VSM_PKG_NAME", - ensure => "${n1k_vsm::n1kv_version}", + package { 'Package_VSM': + ensure => $n1k_vsm::n1kv_version, + name => $VSM_PKG_NAME, } - -> - exec {"Copy_VSM": - command => "/bin/cp $VSM_RPM_Install_Dir/*.iso $VSM_Spool_Dir/$VSM_ISO", - before => Notify["$VSM_Bin_Prepare_Sync_Point"], + -> + exec { 'Copy_VSM': + command => "/bin/cp ${VSM_RPM_Install_Dir}/*.iso ${VSM_Spool_Dir}/${VSM_ISO}", + before => Notify[ $VSM_Bin_Prepare_Sync_Point ], } -> - exec {"Debug-http-cisco-os and Package_VSM": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug-http-cisco-os and Package_VSM \n baseurl=$n1k_vsm::n1kv_source \n descr=>Internal repo for Foreman \n enabled = 1 \n gpgcheck=1 \n gpgkey => $n1kv_source::n1kv_source/RPM-GPG-KEY\n\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug-http-cisco-os and Package_VSM': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug-http-cisco-os and Package_VSM \n baseurl=${n1k_vsm::n1kv_source} \n descr=>Internal repo for Foreman \n enabled = 1 \n gpgcheck=1 \n gpgkey => ${n1kv_source::n1kv_source}/RPM-GPG-KEY\n\" >> ${n1k_vsm::Debug_Log}", } } - "ftp": { - package {"ftp": - name => "ftp", - ensure => "installed", + ftp: { + package { 'ftp': + ensure => installed, + name => 'ftp', } -> - yumrepo {"ftp-cisco-foreman": - baseurl => "$n1k_vsm::n1kv_source", - descr => "Internal repo for Foreman", - enabled => "1", - gpgcheck => "1", - proxy => "_none_", - gpgkey => "${n1k_vsm::n1kv_source}/RPM-GPG-KEY", + yumrepo { 'ftp-cisco-foreman': + baseurl => $n1k_vsm::n1kv_source, + descr => 'Internal repo for Foreman', + enabled => 1, + gpgcheck => 1, + proxy => '_none_', + gpgkey => "${n1k_vsm::n1kv_source}/RPM-GPG-KEY", } -> - package {"Package_VSM": - name => "$VSM_PKG_NAME", - ensure => "${n1k_vsm::n1kv_version}", + package { 'Package_VSM': + ensure => $n1k_vsm::n1kv_version, + name => $VSM_PKG_NAME, } - -> - exec {"Copy_VSM": - command => "/bin/cp $VSM_RPM_Install_Dir/*.iso $VSM_Spool_Dir/$VSM_ISO", - before => Notify["$VSM_Bin_Prepare_Sync_Point"], + -> + exec { 'Copy_VSM': + command => "/bin/cp ${VSM_RPM_Install_Dir}/*.iso ${VSM_Spool_Dir}/${VSM_ISO}", + before => Notify[ $VSM_Bin_Prepare_Sync_Point ], } -> - exec {"Debug-ftp-cisco-os and Package_VSM": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug-ftp-cisco-os and Package_VSM \n baseurl=$n1k_vsm::n1kv_source \n descr=>Internal repo for Foreman \n enabled = 1 \n gpgcheck=1 \n gpgkey => $n1kv_source::n1kv_source/RPM-GPG-KEY\n\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug-ftp-cisco-os and Package_VSM': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug-ftp-cisco-os and Package_VSM \n baseurl=${n1k_vsm::n1kv_source} \n descr=>Internal repo for Foreman \n enabled = 1 \n gpgcheck=1 \n gpgkey => ${n1kv_source::n1kv_source}/RPM-GPG-KEY\n\" >> ${n1k_vsm::Debug_Log}", } - + } - "puppet": { + puppet: { # # make sure the file does not exist # - exec {"File_VSM_Bin_Remove": - command => "/bin/rm -f $VSM_DEST || /bin/true", - before => Notify["$VSM_Bin_Prepare_Sync_Point"], + exec { 'File_VSM_Bin_Remove': + command => "/bin/rm -f ${VSM_DEST} || /bin/true", + before => Notify[ $VSM_Bin_Prepare_Sync_Point ], } -> - file {"File_VSM_Bin_Prepare": - path => "$VSM_DEST", - ensure => "present", - owner => "root", - group => "root", - mode => "664", - source => "$n1k_vsm::n1kv_source", - before => Notify["$VSM_Bin_Prepare_Sync_Point"], + file { 'File_VSM_Bin_Prepare': + ensure => present, + path => $VSM_DEST, + owner => 'root', + group => 'root', + mode => '0664', + source => $n1k_vsm::n1kv_source, + before => Notify[ $VSM_Bin_Prepare_Sync_Point ], } -> - exec {"Exec_RPM_TO_ISO": + exec { 'Exec_RPM_TO_ISO': # # If it's an RPM, we do a local rpm installation ..." # - command => "/bin/rpm -i --force $VSM_DEST && /bin/cp $VSM_RPM_Install_Dir/*.iso $VSM_Spool_Dir/$VSM_ISO", - unless => "/usr/bin/file $VSM_DEST | /bin/grep -c ' ISO '", - before => Notify["$VSM_Bin_Prepare_Sync_Point"], + command => "/bin/rpm -i --force ${VSM_DEST} && /bin/cp ${VSM_RPM_Install_Dir}/*.iso ${VSM_Spool_Dir}/${VSM_ISO}", + unless => '/usr/bin/file $VSM_DEST | /bin/grep -c \' ISO \'', + before => Notify[ $VSM_Bin_Prepare_Sync_Point], } -> - exec {"Debug_File_VSM_Bin_Prepare_Exec_RPM_TO_ISO": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug_File_VSM_Bin_Prepare_Exec_RPM_TO_ISO \n path=$VSM_DEST \n ensure=directory \n owner=root\n group=root\n mode=664\n source=$n1k_vsm::n1kv_source\n \" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_File_VSM_Bin_Prepare_Exec_RPM_TO_ISO': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug_File_VSM_Bin_Prepare_Exec_RPM_TO_ISO \n path=${VSM_DEST} \n ensure=directory \n owner=root\n group=root\n mode=664\n source=${n1k_vsm::n1kv_source}\n \" >> ${n1k_vsm::Debug_Log}", } } default: { - fail(": Unknown sourcing method [$source_method] is not supported") + fail(": Unknown sourcing method [${sourcemethod}] is not supported") } } - notify {"$VSM_Bin_Prepare_Sync_Point":} - + notify { $VSM_Bin_Prepare_Sync_Point :} + # # copy repackiso.py to local place # - file {"File_VSM_Repackage_Script_Name": - path => "$VSM_Repackage_Script", - ensure => "present", - owner => "root", - group => "root", - mode => "774", - source => "puppet:///modules/n1k_vsm/$VSM_Repackage_Script_Name", + file { 'File_VSM_Repackage_Script_Name': + ensure => present, + path => $VSM_Repackage_Script, + owner => 'root', + group => 'root', + mode => '0774', + source => "puppet:///modules/n1k_vsm/${VSM_Repackage_Script_Name}", } -> - exec {"Debug_File_VSM_Repackage_Script_Name": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug_VSM_Repackage_Script_Name \n path=$VSM_Repackage_Script \n ensure=present \n owner=root \n group=root \n mode=774\n source=puppet:///modules/n1k_vsm/$VSM_REPACKAGE_SCRIPT_NAME \n\" >> ${n1k_vsm::Debug_Log}", + exec { 'Debug_File_VSM_Repackage_Script_Name': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Debug_VSM_Repackage_Script_Name \n path=${VSM_Repackage_Script} \n ensure=present \n owner=root \n group=root \n mode=774\n source=puppet:///modules/n1k_vsm/${VSM_Repackage_Script_Name} \n\" >> ${n1k_vsm::Debug_Log}", } # # Now generate ovf xml file and repackage the iso # - exec {"Exec_VSM_Repackage_Script_Name": - command => "${VSM_Repackage_Script} -i$VSM_Spool_Dir/$VSM_ISO -d${n1k_vsm::domainid} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::adminpasswd} -r${n1k_vsm::role} -f${VSM_Spool_Dir}/${n1k_vsm::role}_repacked.iso >> ${n1k_vsm::Debug_Log}", + exec { 'Exec_VSM_Repackage_Script_Name': + command => "${VSM_Repackage_Script} -i${VSM_Spool_Dir}/${VSM_ISO} -d${n1k_vsm::vsm_domain_id} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::vsm_admin_passwd} -r${n1k_vsm::vsm_role} -f${VSM_Spool_Dir}/${n1k_vsm::vsm_role}_repacked.iso >> ${n1k_vsm::Debug_Log}", } -> - exec {"Debug_Exec_VSM_Repackage_Script_Name": - command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_VSM_Repackage_Script_Name\n command=$VSM_Repackage_Script -i$VSM_ISO -d${n1k_vsm::domainid} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::adminpasswd} -r${n1k_vsm::role} -f${VSM_Spool_Dir}/${n1k_vsm::role}_repacked.iso \n\" >> ${n1k_vsm::Debug_Log}" + exec { 'Debug_Exec_VSM_Repackage_Script_Name': + command => "${n1k_vsm::Debug_Print} \"[INFO]\n Exec_VSM_Repackage_Script_Name\n command=${VSM_Repackage_Script} -i${VSM_ISO} -d${n1k_vsm::vsm_domain_id} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::vsm_admin_passwd} -r${n1k_vsm::vsm_role} -f${VSM_Spool_Dir}/${n1k_vsm::vsm_role}_repacked.iso \n\" >> ${n1k_vsm::Debug_Log}" } - File["File_VSM_Spool_Dir"]-> Notify["$VSM_Bin_Prepare_Sync_Point"]->File["File_VSM_Repackage_Script_Name"]->Exec["Exec_VSM_Repackage_Script_Name"] + File['File_VSM_Spool_Dir']->File['File_RPM_Install_Dir']->Notify[$VSM_Bin_Prepare_Sync_Point]->File['File_VSM_Repackage_Script_Name']->Exec['Exec_VSM_Repackage_Script_Name'] } diff --git a/n1k-vsm/metadata.json b/n1k-vsm/metadata.json new file mode 100644 index 000000000..a20689865 --- /dev/null +++ b/n1k-vsm/metadata.json @@ -0,0 +1,28 @@ +{ + "name": "stackforge-n1kv_vsm", + "version": "0.0.2", + "author": "ChingWei Chang, Marga Millet and StackForge Contributors", + "summary": "Puppet module for Cisco Nexus1000v VSM", + "license": "Apache License 2.0", + "source": "git://github.com/stackforge/puppet-n1k-vsm.git", + "project_page": "https://launchpad.net/puppet-n1k-vsm", + "issues_url": "https://bugs.launchpad.net/puppet-n1k-vsm", + "requirements": [ + {"name": "pe","version_requirement": "3.x"}, + {"name": "puppet","version_requirement": "3.x"} + ], + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": ["7"] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": ["12.04","14.04"] + } + ], + "description": "Installs and configures the Nexus1000v Virtual Supervisor module.", + "dependencies": [ + { "name": "stackforge/vswitch", "version_requirement": ">=1.0.0 <2.0.0" } + ] +}