Merge "Upgrade Nova puppet module"
This commit is contained in:
commit
63ee231dc7
@ -1,5 +0,0 @@
|
||||
* 2012-06-12 0.1.1
|
||||
- Fix dependency for automatic forge installation
|
||||
|
||||
* 2012-06-12 0.1.0
|
||||
- Initial release
|
@ -2,8 +2,23 @@ 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-puppet', '~> 2.1.0', :require => false
|
||||
|
||||
gem 'metadata-json-lint'
|
||||
gem 'puppet-lint-param-docs'
|
||||
gem 'puppet-lint-absolute_classname-check'
|
||||
gem 'puppet-lint-absolute_template_path'
|
||||
gem 'puppet-lint-trailing_newline-check'
|
||||
|
||||
# Puppet 4.x related lint checks
|
||||
gem 'puppet-lint-unquoted_string-check'
|
||||
gem 'puppet-lint-leading_zero-check'
|
||||
gem 'puppet-lint-variable_contains_upcase'
|
||||
gem 'puppet-lint-numericvariable'
|
||||
|
||||
gem 'beaker-rspec', :require => false
|
||||
gem 'json'
|
||||
gem 'webmock'
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
|
@ -1,201 +1,13 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
Copyright 2012 OpenStack Foundation
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
1. Definitions.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
@ -1,19 +0,0 @@
|
||||
name 'puppetlabs-nova'
|
||||
version '4.0.0'
|
||||
source 'https://github.com/stackforge/puppet-nova'
|
||||
author 'Puppet Labs'
|
||||
license 'Apache License 2.0'
|
||||
summary 'Puppet Labs Nova Module'
|
||||
description 'Puppet module to install and configure the OpenStack Nova compute service'
|
||||
project_page 'https://launchpad.net/puppet-nova'
|
||||
|
||||
## Add dependencies, if any:
|
||||
dependency 'dprince/qpid', '>= 1.0.0 <2.0.0'
|
||||
dependency 'duritong/sysctl', '>=0.0.1 <1.0.0'
|
||||
dependency 'puppetlabs/cinder', '>=4.0.0 <5.0.0'
|
||||
dependency 'puppetlabs/glance', '>=4.0.0 <5.0.0'
|
||||
dependency 'puppetlabs/inifile', '>=1.0.0 <2.0.0'
|
||||
dependency 'puppetlabs/keystone', '>=4.0.0 <5.0.0'
|
||||
dependency 'puppetlabs/mysql', '>=0.9.0 <3.0.0'
|
||||
dependency 'puppetlabs/rabbitmq', '>=2.0.2 <4.0.0'
|
||||
dependency 'puppetlabs/stdlib', '>=3.2.0'
|
@ -1,10 +0,0 @@
|
||||
h1. Prerequisites
|
||||
|
||||
The openstack repo should be made available:
|
||||
see: http://docs.openstack.org/cactus/openstack-compute/admin/content/installing-the-cloud-controller.html
|
||||
|
||||
This is currently known not to work on 2.6.4.
|
||||
|
||||
Master of this repo is now targetting the essex version of openstack.
|
||||
|
||||
For Diablo support, try the diablo branch of this repo
|
@ -1,7 +1,7 @@
|
||||
nova
|
||||
====
|
||||
|
||||
4.0.0 - 2014.1.0 - Icehouse
|
||||
5.1.0 - 2014.2 - Juno
|
||||
|
||||
#### Table of Contents
|
||||
|
||||
@ -39,7 +39,7 @@ Setup
|
||||
|
||||
### Beginning with nova
|
||||
|
||||
To utilize the nova module's functionality you will need to declare multiple resources. The following is a modified excerpt from the [openstack module](https://github.com/stackfoge/puppet-openstack). This is not an exhaustive list of all the components needed, we recommend you consult and understand the [openstack module](https://github.com/stackfoge/puppet-openstack) and the [core openstack](http://docs.openstack.org) documentation.
|
||||
To utilize the nova module's functionality you will need to declare multiple resources. The following is a modified excerpt from the [openstack module](https://github.com/stackforge/puppet-openstack). This is not an exhaustive list of all the components needed, we recommend you consult and understand the [openstack module](https://github.com/stackforge/puppet-openstack) and the [core openstack](http://docs.openstack.org) documentation.
|
||||
|
||||
```puppet
|
||||
class { 'nova':
|
||||
@ -74,7 +74,6 @@ Limitations
|
||||
|
||||
* Supports libvirt, xenserver and vmware compute drivers.
|
||||
* Tested on EL and Debian derivatives.
|
||||
* The Nova Openstack service depends on a sqlalchemy database. If you are using puppetlabs-mysql to achieve this, there is a parameter called mysql_module that can be used to swap between the two supported versions: 0.9 and 2.2. This is needed because the puppetlabs-mysql module was rewritten and the custom type names have changed between versions.
|
||||
|
||||
Development
|
||||
-----------
|
||||
@ -83,6 +82,23 @@ Developer documentation for the entire puppet-openstack project.
|
||||
|
||||
* https://wiki.openstack.org/wiki/Puppet-openstack#Developer_documentation
|
||||
|
||||
|
||||
Beaker-Rspec
|
||||
------------
|
||||
|
||||
This module has beaker-rspec tests
|
||||
|
||||
To run the tests on the default vagrant node:
|
||||
|
||||
```shell
|
||||
bundle install
|
||||
bundle exec rspec spec/acceptance
|
||||
```
|
||||
|
||||
For more information on writing and running beaker-rspec tests visit the documentation:
|
||||
|
||||
* https://github.com/puppetlabs/beaker/wiki/How-to-Write-a-Beaker-Test-for-a-Module
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
@ -91,6 +107,88 @@ Contributors
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
**5.1.0**
|
||||
|
||||
* move setting of novncproxy_base_url
|
||||
* Added parameters for availability zones configuration
|
||||
* crontab: ensure nova-common is installed before
|
||||
* Correct docs on format for nova::policy data
|
||||
* Allow libvirt secret key setting from param
|
||||
* Fix behaviour of 'set-secret-value virsh' exec
|
||||
* MySQL: change default MySQL collate to utf8_general_ci
|
||||
* Pin puppetlabs-concat to 1.2.1 in fixtures
|
||||
* Make group on /var/log/nova OS specific
|
||||
* IPv6 support for migration check.
|
||||
* Database: add slave_connection support
|
||||
* Correct references to ::nova::rabbit_* variables
|
||||
* Add optional network_api_class parameter to nova::network::neutron class
|
||||
* Add Nova Aggregate support
|
||||
* rpc_backend: simplify parameters
|
||||
* supporting lxc cpu mode Fixing the default cpu_mode from None to none
|
||||
* virsh returns a list of secret uuids, not keyring names
|
||||
* Pin fixtures for stables branches
|
||||
* Add serialproxy configuration
|
||||
* Switch to TLSv1 as SSLv3 is considered insecure and is disabled by default
|
||||
* Disable file injection when using RBD as compute ephemeral storage
|
||||
* Add PCI Passthrough/SR-IOV support
|
||||
* Add Ironic support into nova puppet modules
|
||||
* spec: pin rspec-puppet to 1.0.1
|
||||
* Correct section for cell_type nova.conf parameter
|
||||
* crontab: ensure the script is run with shell
|
||||
* Configure database parameters on the right nodes
|
||||
|
||||
**5.0.0**
|
||||
|
||||
* Stable Juno release
|
||||
* Added tags to all nova packages
|
||||
* Added parameter dhcp_domain to nova class
|
||||
* Updated the [glance] and [neutron] section parameters for Juno
|
||||
* Fixed potential duplicate declaration errors for sysctl::value in nova::network
|
||||
* Fixed dependency cycle in nova::migration::libvirt
|
||||
* Updated the libvirtd init script path for Debian
|
||||
* Added parameters for nova service validation to nova::api
|
||||
* Added nova::policy to control policy.json
|
||||
* Fixed the rabbit_virtual_host default in nova::cells
|
||||
* Bumped stdlib dependency to >=4.0.0
|
||||
* Added force_raw_images parameter to nova::compute class
|
||||
* Replaced usage of the keyword type with the string 'type' since type is a reserved keyword in puppet 3.7
|
||||
* Added parameter ec2_workers to nova::api
|
||||
* Fixed bug in usage of --vlan versus --vlan_start in nova_network provider
|
||||
* Added parameter rabbit_ha_queues to nova class
|
||||
* Added parameter pool to nova_floating type
|
||||
* Added parameters to control whether to configure keystone users
|
||||
* Added nova::cron::archive_deleted_rows class to create a crontab for archiving deleted database rows
|
||||
* Changed the keystone_service to only be configured if the endpoint is to be configured
|
||||
* Added parameter keystone_ec2_url to nova::api
|
||||
* Added the ability to override the keystone service name in ceilometer::keystone::auth
|
||||
* Removed dynamic scoping of File resources in nova class
|
||||
* Add parameter workers to in nova::conductor and deprecate conductor_workers in nova::api
|
||||
* Update nova quota parameters for Juno
|
||||
* Migrated the ceilometer::db::mysql class to use openstacklib::db::mysql and deprecated the mysql_module parameter
|
||||
* Removed deprecation notice for sectionless nova_config names
|
||||
* Added parameter vnc_keymap in nova::compute
|
||||
* Added parameter osapi_v3 to nova::api
|
||||
|
||||
**4.2.0**
|
||||
|
||||
* Added option to configure libvirt service name via class parameters
|
||||
* Added support for multiple SSL APIs
|
||||
* Added option to configure os_region_name in the nova config
|
||||
* Corrected resource dependencies on the nova user
|
||||
* Fixed os version fact comparison for RedHat-based operating systems
|
||||
for specifying service provider
|
||||
* Fixed ssl parameter requirements when using kombu and rabbit
|
||||
* Added class for extended logging options
|
||||
|
||||
**4.1.0**
|
||||
|
||||
* Added API v3 endpoint support.
|
||||
* Added configuration of rbd keyring name.
|
||||
* Added support for run Nova SSL endpoints.
|
||||
* Updated RabbitMQ dependency.
|
||||
* Updated mysql charset to UTF8.
|
||||
* Pinned major gems.
|
||||
|
||||
**4.0.0**
|
||||
|
||||
* Stable Icehouse release.
|
||||
@ -162,7 +260,7 @@ Release Notes
|
||||
|
||||
**2.0.0**
|
||||
|
||||
* Upstream is now part of stackfoge.
|
||||
* Upstream is now part of stackforge.
|
||||
* The ini_file type is now used by nova_config.
|
||||
* Support for nova-conductor added.
|
||||
* Networks can now be labeled by Class['nova::manage::network'].
|
||||
|
@ -1,7 +1,7 @@
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
require 'puppet-lint/tasks/puppet-lint'
|
||||
|
||||
PuppetLint.configuration.fail_on_warnings = false
|
||||
PuppetLint.configuration.fail_on_warnings = true
|
||||
PuppetLint.configuration.send('disable_80chars')
|
||||
PuppetLint.configuration.send('disable_class_parameter_defaults')
|
||||
PuppetLint.configuration.send('disable_class_inherits_from_params_class')
|
||||
|
@ -1 +0,0 @@
|
||||
cert support has only been added for Redhat. Should this be added for Ubuntu?
|
@ -25,30 +25,30 @@
|
||||
# sudo pcs constraint colocation add nova_api_service with nova_vip
|
||||
# sudo pcs constraint colocation add nova_novncproxy_service with nova_vip
|
||||
|
||||
class { 'nova': }
|
||||
class { '::nova': }
|
||||
|
||||
class { 'nova::api':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
admin_password => 'PASSWORD',
|
||||
class { '::nova::api':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
admin_password => 'PASSWORD',
|
||||
}
|
||||
|
||||
class { 'nova::conductor':
|
||||
class { '::nova::conductor':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
}
|
||||
|
||||
class { 'nova::consoleauth':
|
||||
class { '::nova::consoleauth':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
}
|
||||
|
||||
class { 'nova::scheduler':
|
||||
class { '::nova::scheduler':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
}
|
||||
|
||||
class { 'nova::vncproxy':
|
||||
class { '::nova::vncproxy':
|
||||
enabled => false,
|
||||
manage_service => false,
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# assumes that resonable credentials have been stored at
|
||||
# /root/auth
|
||||
source /root/auth
|
||||
|
||||
# get an image to test with
|
||||
#wget http://uec-images.ubuntu.com/releases/11.10/release/ubuntu-11.10-server-cloudimg-amd64-disk1.img
|
||||
|
||||
# import that image into glance
|
||||
#glance add name="Ubuntu 11.10 cloudimg amd64" is_public=true container_format=ovf disk_format=qcow2 < ubuntu-11.10-server-cloudimg-amd64-disk1.img
|
||||
|
||||
#IMAGE_ID=`glance index | grep 'Ubuntu 11.10 cloudimg amd64' | head -1 | awk -F' ' '{print $1}'`
|
||||
|
||||
wget https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img
|
||||
|
||||
glance add name='cirros image' is_public=true container_format=bare disk_format=qcow2 < cirros-0.3.0-x86_64-disk.img
|
||||
|
||||
IMAGE_ID=`glance index | grep 'cirros image' | head -1 | awk -F' ' '{print $1}'`
|
||||
|
||||
# create a pub key
|
||||
ssh-keygen -f /tmp/id_rsa -t rsa -N ''
|
||||
nova keypair-add --pub_key /tmp/id_rsa.pub key1
|
||||
|
||||
nova boot --flavor 1 --image ${IMAGE_ID} --key_name key1 dans_vm
|
||||
|
||||
nova show dans_vm
|
||||
|
||||
# create ec2 credentials
|
||||
keystone ec2-credentials-create
|
@ -1,193 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from nova.rootwrap import filters
|
||||
|
||||
filterlist = [
|
||||
# This line was patched by Puppet
|
||||
filters.CommandFilter("/usr/bin/virsh", "root"),
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-a', device
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-d', device
|
||||
filters.CommandFilter("/sbin/kpartx", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'tune2fs', '-c', 0, '-i', 0, mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: "tune2fs", "-O ^has_journal", part_path
|
||||
# nova/virt/xenapi/vm_utils.py: "tune2fs", "-j", partition_path
|
||||
filters.CommandFilter("/sbin/tune2fs", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'mount', mapped_device, mount_dir
|
||||
# nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'..
|
||||
filters.CommandFilter("/bin/mount", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'umount', mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: 'umount', dev_path
|
||||
filters.CommandFilter("/bin/umount", "root"),
|
||||
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-c', device, image
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-d', device
|
||||
filters.CommandFilter("/usr/bin/qemu-nbd", "root"),
|
||||
|
||||
# nova/virt/disk/loop.py: 'losetup', '--find', '--show', image
|
||||
# nova/virt/disk/loop.py: 'losetup', '--detach', device
|
||||
filters.CommandFilter("/sbin/losetup", "root"),
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-i'
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-m' dev
|
||||
filters.CommandFilter("/usr/bin/guestmount", "root"),
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'fusermount', 'u', mount_dir
|
||||
filters.CommandFilter("/bin/fusermount", "root"),
|
||||
filters.CommandFilter("/usr/bin/fusermount", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'tee', metadata_path
|
||||
# nova/virt/disk/api.py: 'tee', '-a', keyfile
|
||||
# nova/virt/disk/api.py: 'tee', netfile
|
||||
filters.CommandFilter("/usr/bin/tee", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', sshdir
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', netdir
|
||||
filters.CommandFilter("/bin/mkdir", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'chown', 'root', sshdir
|
||||
# nova/virt/disk/api.py: 'chown', 'root:root', netdir
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid(), console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid(), console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', 'root', basepath('disk')
|
||||
# nova/utils.py: 'chown', owner_uid, path
|
||||
filters.CommandFilter("/bin/chown", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'chmod', '700', sshdir
|
||||
# nova/virt/disk/api.py: 'chmod', 755, netdir
|
||||
filters.CommandFilter("/bin/chmod", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'cp', os.path.join(fs...
|
||||
filters.CommandFilter("/bin/cp", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, "address",..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, "address", ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||
filters.CommandFilter("/sbin/ip", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev
|
||||
# nova/network/linux_net.py: 'tunctl', '-b', '-t', dev
|
||||
filters.CommandFilter("/usr/sbin/tunctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
|
||||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-vsctl", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-ofctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/connection.py: 'dd', "if=%s" % virsh_output, ...
|
||||
filters.CommandFilter("/bin/dd", "root"),
|
||||
|
||||
# nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ...
|
||||
filters.CommandFilter("/sbin/iscsiadm", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "parted", "--script", ...
|
||||
# nova/virt/xenapi/vm_utils.py: 'parted', '--script', dev_path, ..*.
|
||||
filters.CommandFilter("/sbin/parted", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: fdisk %(dev_path)s
|
||||
filters.CommandFilter("/sbin/fdisk", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "e2fsck", "-f", "-p", partition_path
|
||||
filters.CommandFilter("/sbin/e2fsck", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "resize2fs", partition_path
|
||||
filters.CommandFilter("/sbin/resize2fs", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd,), '-t', ...
|
||||
filters.CommandFilter("/sbin/iptables-save", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-save", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||
filters.CommandFilter("/sbin/iptables-restore", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-restore", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||
filters.CommandFilter("/usr/bin/arping", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
|
||||
filters.CommandFilter("/sbin/route", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||
filters.CommandFilter("/usr/bin/dhcp_release", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||
filters.KillFilter("/bin/kill", "root",
|
||||
['-9', '-HUP'], ['/usr/sbin/dnsmasq']),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', pid
|
||||
filters.KillFilter("/bin/kill", "root", [''], ['/usr/sbin/radvd']),
|
||||
|
||||
# nova/network/linux_net.py: dnsmasq call
|
||||
filters.DnsmasqFilter("/usr/sbin/dnsmasq", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'),..
|
||||
filters.CommandFilter("/usr/sbin/radvd", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||
filters.CommandFilter("/sbin/brctl", "root"),
|
||||
filters.CommandFilter("/usr/sbin/brctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'mkswap'
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkswap'
|
||||
filters.CommandFilter("/sbin/mkswap", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkfs'
|
||||
filters.CommandFilter("/sbin/mkfs", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'qemu-img'
|
||||
filters.CommandFilter("/usr/bin/qemu-img", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'touch', target
|
||||
filters.CommandFilter("/usr/bin/touch", "root"),
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
filters.ReadFileFilter("/etc/iscsi/initiatorname.iscsi"),
|
||||
|
||||
]
|
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
--- a/manager.py 2012-10-31 14:09:36.153257689 +0400
|
||||
+++ b/manager.py 2012-10-31 14:10:01.261260402 +0400
|
||||
@@ -65,11 +65,11 @@
|
||||
'internal_access_path': internal_access_path,
|
||||
'last_activity_at': time.time()}
|
||||
data = jsonutils.dumps(token_dict)
|
||||
- self.mc.set(token, data, FLAGS.console_token_ttl)
|
||||
+ self.mc.set(token.encode('UTF-8'), data, FLAGS.console_token_ttl)
|
||||
LOG.audit(_("Received Token: %(token)s, %(token_dict)s)"), locals())
|
||||
|
||||
def check_token(self, context, token):
|
||||
- token_str = self.mc.get(token)
|
||||
+ token_str = self.mc.get(token.encode('UTF-8'))
|
||||
token_valid = (token_str is not None)
|
||||
LOG.audit(_("Checking Token: %(token)s, %(token_valid)s)"), locals())
|
||||
if token_valid:
|
||||
|
@ -1 +0,0 @@
|
||||
libguestfs0 libguestfs/update-appliance boolean true
|
@ -1,35 +0,0 @@
|
||||
# Master configuration file for the QEMU driver.
|
||||
# All settings described here are optional - if omitted, sensible
|
||||
# defaults are used.
|
||||
|
||||
# The user ID for QEMU processes run by the system instance.
|
||||
user = "root"
|
||||
|
||||
# The group ID for QEMU processes run by the system instance.
|
||||
group = "root"
|
||||
|
||||
# This is the basic set of devices allowed / required by
|
||||
# all virtual machines.
|
||||
#
|
||||
# As well as this, any configured block backed disks,
|
||||
# all sound device, and all PTY devices are allowed.
|
||||
#
|
||||
# This will only need setting if newer QEMU suddenly
|
||||
# wants some device we don't already know about.
|
||||
#
|
||||
cgroup_device_acl = [
|
||||
"/dev/null", "/dev/full", "/dev/zero",
|
||||
"/dev/random", "/dev/urandom",
|
||||
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
|
||||
"/dev/rtc", "/dev/hpet", '/dev/net/tun',
|
||||
]
|
||||
|
||||
# If clear_emulator_capabilities is enabled, libvirt will drop all
|
||||
# privileged capabilities of the QEmu/KVM emulator. This is enabled by
|
||||
# default.
|
||||
#
|
||||
# Warning: Disabling this option means that a compromised guest can
|
||||
# exploit the privileges and possibly do damage to the host.
|
||||
#
|
||||
clear_emulator_capabilities = 0
|
||||
|
@ -1,254 +0,0 @@
|
||||
commit 0b5a6543d1a7bcac03565abcde2e3888df55084d
|
||||
Author: Devananda van der Veen <devananda.vdv@gmail.com>
|
||||
Date: Wed Jul 18 18:47:25 2012 -0700
|
||||
|
||||
Catch database-has-gone-away errors and retry
|
||||
|
||||
Wrap certain session and query methods, and catch exceptions caused by a
|
||||
failed or broken database connection. When caught, retry the last query
|
||||
in a loop until it succeeds, or until we time out. The time out is
|
||||
configurable with min, max, and increment options. The current defaults
|
||||
will result in 20 retries spread over 155 seconds.
|
||||
|
||||
As a result of better disconnect error handling, we can remove the
|
||||
ping_listener() which generated spurious "SELECT 1" queries.
|
||||
|
||||
However, we can not yet disable pool_reset_on_return; doing so would
|
||||
cause dangling transactions and lead to random failures between threads
|
||||
viewing old versions of the data.
|
||||
|
||||
Fixes bug 1007027.
|
||||
|
||||
Change-Id: If4b20ab75ef712314327a6c8e167a28d89657091
|
||||
|
||||
diff --git a/db/sqlalchemy/session.py b/db/sqlalchemy/session.py
|
||||
index 6e754be..d5f7330 100644
|
||||
--- a/db/sqlalchemy/session.py
|
||||
+++ b/db/sqlalchemy/session.py
|
||||
@@ -21,12 +21,16 @@
|
||||
import re
|
||||
import time
|
||||
|
||||
-from sqlalchemy.exc import DisconnectionError, OperationalError
|
||||
+from sqlalchemy.exc import DisconnectionError
|
||||
+from sqlalchemy.exc import OperationalError
|
||||
import sqlalchemy.interfaces
|
||||
import sqlalchemy.orm
|
||||
-from sqlalchemy.pool import NullPool, StaticPool
|
||||
+from sqlalchemy.pool import NullPool
|
||||
+from sqlalchemy.pool import StaticPool
|
||||
|
||||
import nova.exception
|
||||
+from nova.exception import DBError
|
||||
+from nova.exception import InvalidUnicodeParameter
|
||||
import nova.flags as flags
|
||||
import nova.openstack.common.log as logging
|
||||
|
||||
@@ -47,8 +51,10 @@ def get_session(autocommit=True, expire_on_commit=False):
|
||||
_MAKER = get_maker(engine, autocommit, expire_on_commit)
|
||||
|
||||
session = _MAKER()
|
||||
- session.query = nova.exception.wrap_db_error(session.query)
|
||||
- session.flush = nova.exception.wrap_db_error(session.flush)
|
||||
+ session.begin = wrap_db_error(session.begin)
|
||||
+ session.execute = wrap_db_error(session.execute)
|
||||
+ session.flush = wrap_db_error(session.flush)
|
||||
+ session.query = wrap_db_error(session.query)
|
||||
return session
|
||||
|
||||
|
||||
@@ -66,24 +72,6 @@ def add_regexp_listener(dbapi_con, con_record):
|
||||
dbapi_con.create_function('regexp', 2, regexp)
|
||||
|
||||
|
||||
-def ping_listener(dbapi_conn, connection_rec, connection_proxy):
|
||||
- """
|
||||
- Ensures that MySQL connections checked out of the
|
||||
- pool are alive.
|
||||
-
|
||||
- Borrowed from:
|
||||
- http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f
|
||||
- """
|
||||
- try:
|
||||
- dbapi_conn.cursor().execute('select 1')
|
||||
- except dbapi_conn.OperationalError, ex:
|
||||
- if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
|
||||
- LOG.warn('Got mysql server has gone away: %s', ex)
|
||||
- raise DisconnectionError("Database server went away")
|
||||
- else:
|
||||
- raise
|
||||
-
|
||||
-
|
||||
def is_db_connection_error(args):
|
||||
"""Return True if error in connecting to db."""
|
||||
# NOTE(adam_g): This is currently MySQL specific and needs to be extended
|
||||
@@ -95,6 +83,51 @@ def is_db_connection_error(args):
|
||||
return False
|
||||
|
||||
|
||||
+def wrap_db_error(f):
|
||||
+ """Function wrapper to capture DB errors
|
||||
+
|
||||
+ If an exception is thrown by the wrapped function,
|
||||
+ determine if it represents a database connection error.
|
||||
+ If so, retry the wrapped function, and repeat until it succeeds
|
||||
+ or we reach a configurable maximum number of retries.
|
||||
+ If it is not a connection error, or we exceeded the retry limit,
|
||||
+ raise a DBError.
|
||||
+
|
||||
+ """
|
||||
+ def _wrap_db_error(*args, **kwargs):
|
||||
+ next_interval = FLAGS.sql_retry_interval
|
||||
+ remaining = FLAGS.sql_max_retries
|
||||
+ if remaining == -1:
|
||||
+ remaining = 'infinite'
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return f(*args, **kwargs)
|
||||
+ except UnicodeEncodeError:
|
||||
+ raise InvalidUnicodeParameter()
|
||||
+ except OperationalError, e:
|
||||
+ if is_db_connection_error(e.args[0]):
|
||||
+ if remaining == 0:
|
||||
+ LOG.exception(_('DB exceeded retry limit.'))
|
||||
+ raise DBError(e)
|
||||
+ if remaining != 'infinite':
|
||||
+ remaining -= 1
|
||||
+ LOG.exception(_('DB connection error, '
|
||||
+ 'retrying in %i seconds.') % next_interval)
|
||||
+ time.sleep(next_interval)
|
||||
+ if FLAGS.sql_inc_retry_interval:
|
||||
+ next_interval = min(next_interval * 2,
|
||||
+ FLAGS.sql_max_retry_interval)
|
||||
+ else:
|
||||
+ LOG.exception(_('DB exception wrapped.'))
|
||||
+ raise DBError(e)
|
||||
+ except Exception, e:
|
||||
+ LOG.exception(_('DB exception wrapped.'))
|
||||
+ raise DBError(e)
|
||||
+
|
||||
+ _wrap_db_error.func_name = f.func_name
|
||||
+ return _wrap_db_error
|
||||
+
|
||||
+
|
||||
def get_engine():
|
||||
"""Return a SQLAlchemy engine."""
|
||||
global _ENGINE
|
||||
@@ -122,9 +155,7 @@ def get_engine():
|
||||
|
||||
_ENGINE = sqlalchemy.create_engine(FLAGS.sql_connection, **engine_args)
|
||||
|
||||
- if 'mysql' in connection_dict.drivername:
|
||||
- sqlalchemy.event.listen(_ENGINE, 'checkout', ping_listener)
|
||||
- elif "sqlite" in connection_dict.drivername:
|
||||
+ if "sqlite" in connection_dict.drivername:
|
||||
if not FLAGS.sqlite_synchronous:
|
||||
sqlalchemy.event.listen(_ENGINE, 'connect',
|
||||
synchronous_switch_listener)
|
||||
@@ -142,6 +173,7 @@ def get_engine():
|
||||
if not is_db_connection_error(e.args[0]):
|
||||
raise
|
||||
|
||||
+ next_interval = FLAGS.sql_retry_interval
|
||||
remaining = FLAGS.sql_max_retries
|
||||
if remaining == -1:
|
||||
remaining = 'infinite'
|
||||
@@ -150,7 +182,7 @@ def get_engine():
|
||||
LOG.warn(msg % remaining)
|
||||
if remaining != 'infinite':
|
||||
remaining -= 1
|
||||
- time.sleep(FLAGS.sql_retry_interval)
|
||||
+ time.sleep(next_interval)
|
||||
try:
|
||||
_ENGINE.connect()
|
||||
break
|
||||
@@ -158,14 +190,22 @@ def get_engine():
|
||||
if (remaining != 'infinite' and remaining == 0) or \
|
||||
not is_db_connection_error(e.args[0]):
|
||||
raise
|
||||
+ if FLAGS.sql_inc_retry_interval:
|
||||
+ next_interval = min(next_interval * 2,
|
||||
+ FLAGS.sql_max_retry_interval)
|
||||
+
|
||||
return _ENGINE
|
||||
|
||||
|
||||
def get_maker(engine, autocommit=True, expire_on_commit=False):
|
||||
"""Return a SQLAlchemy sessionmaker using the given engine."""
|
||||
+ query = sqlalchemy.orm.query.Query
|
||||
+ query.all = wrap_db_error(query.all)
|
||||
+ query.first = wrap_db_error(query.first)
|
||||
return sqlalchemy.orm.sessionmaker(bind=engine,
|
||||
autocommit=autocommit,
|
||||
- expire_on_commit=expire_on_commit)
|
||||
+ expire_on_commit=expire_on_commit,
|
||||
+ query_cls=query)
|
||||
|
||||
|
||||
def debug_mysql_do_query():
|
||||
@@ -185,7 +225,7 @@ def debug_mysql_do_query():
|
||||
continue
|
||||
if file.endswith('utils.py') and method == '_inner':
|
||||
continue
|
||||
- if file.endswith('exception.py') and method == '_wrap':
|
||||
+ if file.endswith('session.py') and method == '_wrap_db_error':
|
||||
continue
|
||||
# nova/db/api is just a wrapper around nova/db/sqlalchemy/api
|
||||
if file.endswith('nova/db/api.py'):
|
||||
diff --git a/exception.py b/exception.py
|
||||
index c9f339e..7ec7a9e 100644
|
||||
--- a/exception.py
|
||||
+++ b/exception.py
|
||||
@@ -62,19 +62,6 @@ class ProcessExecutionError(IOError):
|
||||
IOError.__init__(self, message)
|
||||
|
||||
|
||||
-def wrap_db_error(f):
|
||||
- def _wrap(*args, **kwargs):
|
||||
- try:
|
||||
- return f(*args, **kwargs)
|
||||
- except UnicodeEncodeError:
|
||||
- raise InvalidUnicodeParameter()
|
||||
- except Exception, e:
|
||||
- LOG.exception(_('DB exception wrapped.'))
|
||||
- raise DBError(e)
|
||||
- _wrap.func_name = f.func_name
|
||||
- return _wrap
|
||||
-
|
||||
-
|
||||
def wrap_exception(notifier=None, publisher_id=None, event_type=None,
|
||||
level=None):
|
||||
"""This decorator wraps a method to catch any exceptions that may
|
||||
diff --git a/flags.py b/flags.py
|
||||
index 76766b7..40f83b5 100644
|
||||
--- a/flags.py
|
||||
+++ b/flags.py
|
||||
@@ -258,15 +258,23 @@ global_opts = [
|
||||
default=True,
|
||||
help='If passed, use synchronous mode for sqlite'),
|
||||
cfg.IntOpt('sql_idle_timeout',
|
||||
- default=3600,
|
||||
- help='timeout before idle sql connections are reaped'),
|
||||
+ default=30,
|
||||
+ help='seconds before idle sql connections are reaped'),
|
||||
cfg.IntOpt('sql_max_retries',
|
||||
- default=10,
|
||||
- help='maximum db connection retries during startup. '
|
||||
+ default=20,
|
||||
+ help='maximum sql connection retries before error is raised. '
|
||||
'(setting -1 implies an infinite retry count)'),
|
||||
cfg.IntOpt('sql_retry_interval',
|
||||
+ default=1,
|
||||
+ help='seconds between sql connection retries'),
|
||||
+ cfg.BoolOpt('sql_inc_retry_interval',
|
||||
+ default=True,
|
||||
+ help='Whether to increase interval between sql connection '
|
||||
+ 'retries, up to sql_max_retry_interval'),
|
||||
+ cfg.IntOpt('sql_max_retry_interval',
|
||||
default=10,
|
||||
- help='interval between retries of opening a sql connection'),
|
||||
+ help='max seconds between sql connection retries, if '
|
||||
+ 'sql_inc_retry_interval is enabled'),
|
||||
cfg.StrOpt('compute_manager',
|
||||
default='nova.compute.manager.ComputeManager',
|
||||
help='full class name for the Manager for compute'),
|
@ -1,85 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
# upstart-job
|
||||
#
|
||||
# Symlink target for initscripts that have been converted to Upstart.
|
||||
|
||||
set -e
|
||||
|
||||
INITSCRIPT="$(basename "$0")"
|
||||
JOB="${INITSCRIPT%.sh}"
|
||||
|
||||
if [ "$JOB" = "upstart-job" ]; then
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: upstart-job JOB COMMAND" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JOB="$1"
|
||||
INITSCRIPT="$1"
|
||||
shift
|
||||
else
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 COMMAND" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
COMMAND="$1"
|
||||
shift
|
||||
|
||||
|
||||
if [ -z "$DPKG_MAINTSCRIPT_PACKAGE" ]; then
|
||||
ECHO=echo
|
||||
else
|
||||
ECHO=:
|
||||
fi
|
||||
|
||||
$ECHO "Rather than invoking init scripts through /etc/init.d, use the service(8)"
|
||||
$ECHO "utility, e.g. service $INITSCRIPT $COMMAND"
|
||||
|
||||
case $COMMAND in
|
||||
status)
|
||||
$ECHO
|
||||
$ECHO "Since the script you are attempting to invoke has been converted to an"
|
||||
$ECHO "Upstart job, you may also use the $COMMAND(8) utility, e.g. $COMMAND $JOB"
|
||||
$COMMAND "$JOB"
|
||||
;;
|
||||
start|stop)
|
||||
$ECHO
|
||||
$ECHO "Since the script you are attempting to invoke has been converted to an"
|
||||
$ECHO "Upstart job, you may also use the $COMMAND(8) utility, e.g. $COMMAND $JOB"
|
||||
if status "$JOB" 2>/dev/null | grep -q ' start/'; then
|
||||
RUNNING=1
|
||||
fi
|
||||
if [ -z "$RUNNING" ] && [ "$COMMAND" = "stop" ]; then
|
||||
exit 0
|
||||
elif [ -n "$RUNNING" ] && [ "$COMMAND" = "start" ]; then
|
||||
exit 0
|
||||
fi
|
||||
$COMMAND "$JOB"
|
||||
;;
|
||||
restart)
|
||||
$ECHO
|
||||
$ECHO "Since the script you are attempting to invoke has been converted to an"
|
||||
$ECHO "Upstart job, you may also use the stop(8) and then start(8) utilities,"
|
||||
$ECHO "e.g. stop $JOB ; start $JOB. The restart(8) utility is also available."
|
||||
if status "$JOB" 2>/dev/null | grep -q ' start/'; then
|
||||
RUNNING=1
|
||||
fi
|
||||
if [ -n "$RUNNING" ] ; then
|
||||
stop "$JOB"
|
||||
fi
|
||||
start "$JOB"
|
||||
;;
|
||||
reload|force-reload)
|
||||
$ECHO
|
||||
$ECHO "Since the script you are attempting to invoke has been converted to an"
|
||||
$ECHO "Upstart job, you may also use the reload(8) utility, e.g. reload $JOB"
|
||||
reload "$JOB"
|
||||
;;
|
||||
*)
|
||||
$ECHO
|
||||
$ECHO "The script you are attempting to invoke has been converted to an Upstart" 1>&2
|
||||
$ECHO "job, but $COMMAND is not supported for Upstart jobs." 1>&2
|
||||
exit 1
|
||||
esac
|
@ -1,136 +0,0 @@
|
||||
--- a/openstack/common/rpc/impl_qpid.py
|
||||
+++ a/openstack/common/rpc/impl_qpid.py
|
||||
@@ -41,6 +41,9 @@
|
||||
cfg.StrOpt('qpid_port',
|
||||
default='5672',
|
||||
help='Qpid broker port'),
|
||||
+ cfg.ListOpt('qpid_hosts',
|
||||
+ default=['$qpid_hostname:$qpid_port'],
|
||||
+ help='Qpid HA cluster host:port pairs'),
|
||||
cfg.StrOpt('qpid_username',
|
||||
default='',
|
||||
help='Username for qpid connection'),
|
||||
@@ -50,24 +53,6 @@
|
||||
cfg.StrOpt('qpid_sasl_mechanisms',
|
||||
default='',
|
||||
help='Space separated list of SASL mechanisms to use for auth'),
|
||||
- cfg.BoolOpt('qpid_reconnect',
|
||||
- default=True,
|
||||
- help='Automatically reconnect'),
|
||||
- cfg.IntOpt('qpid_reconnect_timeout',
|
||||
- default=0,
|
||||
- help='Reconnection timeout in seconds'),
|
||||
- cfg.IntOpt('qpid_reconnect_limit',
|
||||
- default=0,
|
||||
- help='Max reconnections before giving up'),
|
||||
- cfg.IntOpt('qpid_reconnect_interval_min',
|
||||
- default=0,
|
||||
- help='Minimum seconds between reconnection attempts'),
|
||||
- cfg.IntOpt('qpid_reconnect_interval_max',
|
||||
- default=0,
|
||||
- help='Maximum seconds between reconnection attempts'),
|
||||
- cfg.IntOpt('qpid_reconnect_interval',
|
||||
- default=0,
|
||||
- help='Equivalent to setting max and min to the same value'),
|
||||
cfg.IntOpt('qpid_heartbeat',
|
||||
default=60,
|
||||
help='Seconds between connection keepalive heartbeats'),
|
||||
@@ -296,47 +281,32 @@
|
||||
if server_params is None:
|
||||
server_params = {}
|
||||
|
||||
- default_params = dict(hostname=self.conf.qpid_hostname,
|
||||
- port=self.conf.qpid_port,
|
||||
+ default_params = dict(hosts=self.conf.qpid_hosts,
|
||||
username=self.conf.qpid_username,
|
||||
password=self.conf.qpid_password)
|
||||
|
||||
- params = server_params
|
||||
+ self.params = server_params
|
||||
for key in default_params.keys():
|
||||
- params.setdefault(key, default_params[key])
|
||||
+ self.params.setdefault(key, default_params[key])
|
||||
|
||||
- self.broker = params['hostname'] + ":" + str(params['port'])
|
||||
+ self.brokers = self.params['hosts']
|
||||
+ self.create_connection(self.brokers[0])
|
||||
+ self.reconnect()
|
||||
+
|
||||
+ def create_connection(self, broker):
|
||||
# Create the connection - this does not open the connection
|
||||
- self.connection = qpid.messaging.Connection(self.broker)
|
||||
+ self.connection = qpid.messaging.Connection(broker)
|
||||
|
||||
# Check if flags are set and if so set them for the connection
|
||||
# before we call open
|
||||
- self.connection.username = params['username']
|
||||
- self.connection.password = params['password']
|
||||
+ self.connection.username = self.params['username']
|
||||
+ self.connection.password = self.params['password']
|
||||
+ self.connection.reconnect = False
|
||||
self.connection.sasl_mechanisms = self.conf.qpid_sasl_mechanisms
|
||||
- self.connection.reconnect = self.conf.qpid_reconnect
|
||||
- if self.conf.qpid_reconnect_timeout:
|
||||
- self.connection.reconnect_timeout = (
|
||||
- self.conf.qpid_reconnect_timeout)
|
||||
- if self.conf.qpid_reconnect_limit:
|
||||
- self.connection.reconnect_limit = self.conf.qpid_reconnect_limit
|
||||
- if self.conf.qpid_reconnect_interval_max:
|
||||
- self.connection.reconnect_interval_max = (
|
||||
- self.conf.qpid_reconnect_interval_max)
|
||||
- if self.conf.qpid_reconnect_interval_min:
|
||||
- self.connection.reconnect_interval_min = (
|
||||
- self.conf.qpid_reconnect_interval_min)
|
||||
- if self.conf.qpid_reconnect_interval:
|
||||
- self.connection.reconnect_interval = (
|
||||
- self.conf.qpid_reconnect_interval)
|
||||
self.connection.heartbeat = self.conf.qpid_heartbeat
|
||||
self.connection.protocol = self.conf.qpid_protocol
|
||||
self.connection.tcp_nodelay = self.conf.qpid_tcp_nodelay
|
||||
|
||||
- # Open is part of reconnect -
|
||||
- # NOTE(WGH) not sure we need this with the reconnect flags
|
||||
- self.reconnect()
|
||||
-
|
||||
def _register_consumer(self, consumer):
|
||||
self.consumers[str(consumer.get_receiver())] = consumer
|
||||
|
||||
@@ -351,23 +321,32 @@
|
||||
except qpid.messaging.exceptions.ConnectionError:
|
||||
pass
|
||||
|
||||
+ delay = 1
|
||||
+ attempt = 0
|
||||
while True:
|
||||
+ broker = self.brokers[attempt % len(self.brokers)]
|
||||
+ attempt += 1
|
||||
try:
|
||||
+ self.create_connection(broker)
|
||||
self.connection.open()
|
||||
except qpid.messaging.exceptions.ConnectionError, e:
|
||||
- LOG.error(_('Unable to connect to AMQP server: %s'), e)
|
||||
- time.sleep(self.conf.qpid_reconnect_interval or 1)
|
||||
+ LOG.error(_('Unable to connect to AMQP server %s: %s'), broker, e)
|
||||
+ time.sleep(delay)
|
||||
+ delay = min(2*delay, 60)
|
||||
else:
|
||||
break
|
||||
|
||||
- LOG.info(_('Connected to AMQP server on %s'), self.broker)
|
||||
+ LOG.info(_('Connected to AMQP server on %s'), broker)
|
||||
|
||||
self.session = self.connection.session()
|
||||
|
||||
- for consumer in self.consumers.itervalues():
|
||||
- consumer.reconnect(self.session)
|
||||
-
|
||||
if self.consumers:
|
||||
+ consumers = self.consumers
|
||||
+ self.consumers = {}
|
||||
+ for consumer in consumers.itervalues():
|
||||
+ consumer.reconnect(self.session)
|
||||
+ self._register_consumer(consumer)
|
||||
+
|
||||
LOG.debug(_("Re-established AMQP queues"))
|
||||
|
||||
def ensure(self, error_callback, method, *args, **kwargs):
|
@ -1,381 +0,0 @@
|
||||
From 32aae43c94d692d02324c1a299996e5f979f9613 Mon Sep 17 00:00:00 2001
|
||||
From: Eugene Kirpichov <ekirpichov@gmail.com>
|
||||
Date: Tue, 30 Oct 2012 11:30:59 +0000
|
||||
Subject: [PATCH] Support for several HA RabbitMQ servers.
|
||||
|
||||
Backport from https://review.openstack.org/#/c/13665/
|
||||
|
||||
Change-Id: Ib44abf115b42c3df42771344f6722ce1db043bbd
|
||||
---
|
||||
openstack/common/network_utils.py | 68 ++++++++++++++++++
|
||||
openstack/common/rpc/impl_kombu.py | 120 +++++++++++++++++++++----------
|
||||
openstack-common.conf | 2 +-
|
||||
3 files changed, 150 insertions(+), 40 deletions(-)
|
||||
create mode 100644 openstack/common/network_utils.py
|
||||
|
||||
diff --git a/openstack/common/network_utils.py b/openstack/common/network_utils.py
|
||||
new file mode 100644
|
||||
index 0000000..69f6732
|
||||
--- /dev/null
|
||||
+++ b/openstack/common/network_utils.py
|
||||
@@ -0,0 +1,68 @@
|
||||
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
+
|
||||
+# Copyright 2012 OpenStack LLC.
|
||||
+# All Rights Reserved.
|
||||
+#
|
||||
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
+# not use this file except in compliance with the License. You may obtain
|
||||
+# a copy of the License at
|
||||
+#
|
||||
+# http://www.apache.org/licenses/LICENSE-2.0
|
||||
+#
|
||||
+# Unless required by applicable law or agreed to in writing, software
|
||||
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
+# License for the specific language governing permissions and limitations
|
||||
+# under the License.
|
||||
+
|
||||
+"""
|
||||
+Network-related utilities and helper functions.
|
||||
+"""
|
||||
+
|
||||
+import logging
|
||||
+
|
||||
+LOG = logging.getLogger(__name__)
|
||||
+
|
||||
+
|
||||
+def parse_host_port(address, default_port=None):
|
||||
+ """
|
||||
+ Interpret a string as a host:port pair.
|
||||
+ An IPv6 address MUST be escaped if accompanied by a port,
|
||||
+ because otherwise ambiguity ensues: 2001:db8:85a3::8a2e:370:7334
|
||||
+ means both [2001:db8:85a3::8a2e:370:7334] and
|
||||
+ [2001:db8:85a3::8a2e:370]:7334.
|
||||
+
|
||||
+ >>> parse_host_port('server01:80')
|
||||
+ ('server01', 80)
|
||||
+ >>> parse_host_port('server01')
|
||||
+ ('server01', None)
|
||||
+ >>> parse_host_port('server01', default_port=1234)
|
||||
+ ('server01', 1234)
|
||||
+ >>> parse_host_port('[::1]:80')
|
||||
+ ('::1', 80)
|
||||
+ >>> parse_host_port('[::1]')
|
||||
+ ('::1', None)
|
||||
+ >>> parse_host_port('[::1]', default_port=1234)
|
||||
+ ('::1', 1234)
|
||||
+ >>> parse_host_port('2001:db8:85a3::8a2e:370:7334', default_port=1234)
|
||||
+ ('2001:db8:85a3::8a2e:370:7334', 1234)
|
||||
+
|
||||
+ """
|
||||
+ if address[0] == '[':
|
||||
+ # Escaped ipv6
|
||||
+ _host, _port = address[1:].split(']')
|
||||
+ host = _host
|
||||
+ if ':' in _port:
|
||||
+ port = _port.split(':')[1]
|
||||
+ else:
|
||||
+ port = default_port
|
||||
+ else:
|
||||
+ if address.count(':') == 1:
|
||||
+ host, port = address.split(':')
|
||||
+ else:
|
||||
+ # 0 means ipv4, >1 means ipv6.
|
||||
+ # We prohibit unescaped ipv6 addresses with port.
|
||||
+ host = address
|
||||
+ port = default_port
|
||||
+
|
||||
+ return (host, None if port is None else int(port))
|
||||
diff --git a/openstack/common/rpc/impl_kombu.py b/openstack/common/rpc/impl_kombu.py
|
||||
index fff1ed9..3469a9b 100644
|
||||
--- a/openstack/common/rpc/impl_kombu.py
|
||||
+++ b/openstack/common/rpc/impl_kombu.py
|
||||
@@ -33,6 +33,7 @@ from nova.openstack.common import cfg
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common.rpc import amqp as rpc_amqp
|
||||
from nova.openstack.common.rpc import common as rpc_common
|
||||
+from nova.openstack.common import network_utils
|
||||
|
||||
kombu_opts = [
|
||||
cfg.StrOpt('kombu_ssl_version',
|
||||
@@ -50,10 +51,13 @@ kombu_opts = [
|
||||
'(valid only if SSL enabled)')),
|
||||
cfg.StrOpt('rabbit_host',
|
||||
default='localhost',
|
||||
- help='the RabbitMQ host'),
|
||||
+ help='The RabbitMQ broker address where a single node is used'),
|
||||
cfg.IntOpt('rabbit_port',
|
||||
default=5672,
|
||||
- help='the RabbitMQ port'),
|
||||
+ help='The RabbitMQ broker port where a single node is used'),
|
||||
+ cfg.ListOpt('rabbit_hosts',
|
||||
+ default=['$rabbit_host:$rabbit_port'],
|
||||
+ help='RabbitMQ HA cluster host:port pairs'),
|
||||
cfg.BoolOpt('rabbit_use_ssl',
|
||||
default=False,
|
||||
help='connect over SSL for RabbitMQ'),
|
||||
@@ -80,6 +84,11 @@ kombu_opts = [
|
||||
cfg.BoolOpt('rabbit_durable_queues',
|
||||
default=False,
|
||||
help='use durable queues in RabbitMQ'),
|
||||
+ cfg.BoolOpt('rabbit_ha_queues',
|
||||
+ default=False,
|
||||
+ help='use H/A queues in RabbitMQ (x-ha-policy: all).'
|
||||
+ 'You need to wipe RabbitMQ database when '
|
||||
+ 'changing this option.'),
|
||||
|
||||
]
|
||||
|
||||
@@ -88,6 +97,20 @@ cfg.CONF.register_opts(kombu_opts)
|
||||
LOG = rpc_common.LOG
|
||||
|
||||
|
||||
+def _get_queue_arguments(conf):
|
||||
+ """Construct the arguments for declaring a queue.
|
||||
+
|
||||
+ If the rabbit_ha_queues option is set, we declare a mirrored queue
|
||||
+ as described here:
|
||||
+
|
||||
+ http://www.rabbitmq.com/ha.html
|
||||
+
|
||||
+ Setting x-ha-policy to all means that the queue will be mirrored
|
||||
+ to all nodes in the cluster.
|
||||
+ """
|
||||
+ return {'x-ha-policy': 'all'} if conf.rabbit_ha_queues else {}
|
||||
+
|
||||
+
|
||||
class ConsumerBase(object):
|
||||
"""Consumer base class."""
|
||||
|
||||
@@ -172,6 +195,7 @@ class DirectConsumer(ConsumerBase):
|
||||
"""
|
||||
# Default options
|
||||
options = {'durable': False,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': True,
|
||||
'exclusive': True}
|
||||
options.update(kwargs)
|
||||
@@ -207,6 +231,7 @@ class TopicConsumer(ConsumerBase):
|
||||
"""
|
||||
# Default options
|
||||
options = {'durable': conf.rabbit_durable_queues,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': False,
|
||||
'exclusive': False}
|
||||
options.update(kwargs)
|
||||
@@ -242,6 +267,7 @@ class FanoutConsumer(ConsumerBase):
|
||||
|
||||
# Default options
|
||||
options = {'durable': False,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': True,
|
||||
'exclusive': True}
|
||||
options.update(kwargs)
|
||||
@@ -289,6 +315,7 @@ class DirectPublisher(Publisher):
|
||||
"""
|
||||
|
||||
options = {'durable': False,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': True,
|
||||
'exclusive': True}
|
||||
options.update(kwargs)
|
||||
@@ -304,6 +331,7 @@ class TopicPublisher(Publisher):
|
||||
Kombu options may be passed as keyword args to override defaults
|
||||
"""
|
||||
options = {'durable': conf.rabbit_durable_queues,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': False,
|
||||
'exclusive': False}
|
||||
options.update(kwargs)
|
||||
@@ -319,6 +347,7 @@ class FanoutPublisher(Publisher):
|
||||
Kombu options may be passed as keyword args to override defaults
|
||||
"""
|
||||
options = {'durable': False,
|
||||
+ 'queue_arguments': _get_queue_arguments(conf),
|
||||
'auto_delete': True,
|
||||
'exclusive': True}
|
||||
options.update(kwargs)
|
||||
@@ -331,6 +360,7 @@ class NotifyPublisher(TopicPublisher):
|
||||
|
||||
def __init__(self, conf, channel, topic, **kwargs):
|
||||
self.durable = kwargs.pop('durable', conf.rabbit_durable_queues)
|
||||
+ self.queue_arguments = _get_queue_arguments(conf)
|
||||
super(NotifyPublisher, self).__init__(conf, channel, topic, **kwargs)
|
||||
|
||||
def reconnect(self, channel):
|
||||
@@ -343,7 +373,8 @@ class NotifyPublisher(TopicPublisher):
|
||||
exchange=self.exchange,
|
||||
durable=self.durable,
|
||||
name=self.routing_key,
|
||||
- routing_key=self.routing_key)
|
||||
+ routing_key=self.routing_key,
|
||||
+ queue_arguments=self.queue_arguments)
|
||||
queue.declare()
|
||||
|
||||
|
||||
@@ -368,31 +399,39 @@ class Connection(object):
|
||||
|
||||
if server_params is None:
|
||||
server_params = {}
|
||||
-
|
||||
# Keys to translate from server_params to kombu params
|
||||
server_params_to_kombu_params = {'username': 'userid'}
|
||||
|
||||
- params = {}
|
||||
- for sp_key, value in server_params.iteritems():
|
||||
- p_key = server_params_to_kombu_params.get(sp_key, sp_key)
|
||||
- params[p_key] = value
|
||||
+ ssl_params = self._fetch_ssl_params()
|
||||
+ params_list = []
|
||||
+ for adr in self.conf.rabbit_hosts:
|
||||
+ hostname, port = network_utils.parse_host_port(
|
||||
+ adr, default_port=self.conf.rabbit_port)
|
||||
|
||||
- params.setdefault('hostname', self.conf.rabbit_host)
|
||||
- params.setdefault('port', self.conf.rabbit_port)
|
||||
- params.setdefault('userid', self.conf.rabbit_userid)
|
||||
- params.setdefault('password', self.conf.rabbit_password)
|
||||
- params.setdefault('virtual_host', self.conf.rabbit_virtual_host)
|
||||
+ params = {}
|
||||
|
||||
- self.params = params
|
||||
+ for sp_key, value in server_params.iteritems():
|
||||
+ p_key = server_params_to_kombu_params.get(sp_key, sp_key)
|
||||
+ params[p_key] = value
|
||||
|
||||
- if self.conf.fake_rabbit:
|
||||
- self.params['transport'] = 'memory'
|
||||
- self.memory_transport = True
|
||||
- else:
|
||||
- self.memory_transport = False
|
||||
+ params.setdefault('hostname', hostname)
|
||||
+ params.setdefault('port', port)
|
||||
+ params.setdefault('userid', self.conf.rabbit_userid)
|
||||
+ params.setdefault('password', self.conf.rabbit_password)
|
||||
+ params.setdefault('virtual_host', self.conf.rabbit_virtual_host)
|
||||
+
|
||||
+ if self.conf.fake_rabbit:
|
||||
+ params['transport'] = 'memory'
|
||||
+ else:
|
||||
+ params['transport'] = 'pyamqp'
|
||||
+ if self.conf.rabbit_use_ssl:
|
||||
+ params['ssl'] = ssl_params
|
||||
|
||||
- if self.conf.rabbit_use_ssl:
|
||||
- self.params['ssl'] = self._fetch_ssl_params()
|
||||
+ params_list.append(params)
|
||||
+
|
||||
+ self.params_list = params_list
|
||||
+
|
||||
+ self.memory_transport = self.conf.fake_rabbit
|
||||
|
||||
self.connection = None
|
||||
self.reconnect()
|
||||
@@ -422,23 +461,24 @@ class Connection(object):
|
||||
# Return the extended behavior
|
||||
return ssl_params
|
||||
|
||||
- def _connect(self):
|
||||
+ def _connect(self, params):
|
||||
"""Connect to rabbit. Re-establish any queues that may have
|
||||
been declared before if we are reconnecting. Exceptions should
|
||||
be handled by the caller.
|
||||
"""
|
||||
if self.connection:
|
||||
LOG.info(_("Reconnecting to AMQP server on "
|
||||
- "%(hostname)s:%(port)d") % self.params)
|
||||
+ "%(hostname)s:%(port)d") % params)
|
||||
try:
|
||||
self.connection.close()
|
||||
- except self.connection_errors:
|
||||
+ except (self.connection_errors, self.channel_errors):
|
||||
pass
|
||||
# Setting this in case the next statement fails, though
|
||||
# it shouldn't be doing any network operations, yet.
|
||||
self.connection = None
|
||||
- self.connection = kombu.connection.BrokerConnection(**self.params)
|
||||
+ self.connection = kombu.connection.BrokerConnection(**params)
|
||||
self.connection_errors = self.connection.connection_errors
|
||||
+ self.channel_errors = self.connection.channel_errors
|
||||
if self.memory_transport:
|
||||
# Kludge to speed up tests.
|
||||
self.connection.transport.polling_interval = 0.0
|
||||
@@ -450,8 +490,8 @@ class Connection(object):
|
||||
self.channel._new_queue('ae.undeliver')
|
||||
for consumer in self.consumers:
|
||||
consumer.reconnect(self.channel)
|
||||
- LOG.info(_('Connected to AMQP server on %(hostname)s:%(port)d'),
|
||||
- self.params)
|
||||
+ LOG.info(_('Connected to AMQP server on %(hostname)s:%(port)d') %
|
||||
+ params)
|
||||
|
||||
def reconnect(self):
|
||||
"""Handles reconnecting and re-establishing queues.
|
||||
@@ -464,11 +504,12 @@ class Connection(object):
|
||||
|
||||
attempt = 0
|
||||
while True:
|
||||
+ params = self.params_list[attempt % len(self.params_list)]
|
||||
attempt += 1
|
||||
try:
|
||||
- self._connect()
|
||||
+ self._connect(params)
|
||||
return
|
||||
- except (self.connection_errors, IOError), e:
|
||||
+ except (IOError, self.connection_errors, self.channel_errors) as e:
|
||||
pass
|
||||
except Exception, e:
|
||||
# NOTE(comstud): Unfortunately it's possible for amqplib
|
||||
@@ -483,12 +524,12 @@ class Connection(object):
|
||||
log_info = {}
|
||||
log_info['err_str'] = str(e)
|
||||
log_info['max_retries'] = self.max_retries
|
||||
- log_info.update(self.params)
|
||||
+ log_info.update(params)
|
||||
|
||||
if self.max_retries and attempt == self.max_retries:
|
||||
- LOG.exception(_('Unable to connect to AMQP server on '
|
||||
- '%(hostname)s:%(port)d after %(max_retries)d '
|
||||
- 'tries: %(err_str)s') % log_info)
|
||||
+ LOG.error(_('Unable to connect to AMQP server on '
|
||||
+ '%(hostname)s:%(port)d after %(max_retries)d '
|
||||
+ 'tries: %(err_str)s') % log_info)
|
||||
# NOTE(comstud): Copied from original code. There's
|
||||
# really no better recourse because if this was a queue we
|
||||
# need to consume on, we have no way to consume anymore.
|
||||
@@ -502,9 +543,9 @@ class Connection(object):
|
||||
sleep_time = min(sleep_time, self.interval_max)
|
||||
|
||||
log_info['sleep_time'] = sleep_time
|
||||
- LOG.exception(_('AMQP server on %(hostname)s:%(port)d is'
|
||||
- ' unreachable: %(err_str)s. Trying again in '
|
||||
- '%(sleep_time)d seconds.') % log_info)
|
||||
+ LOG.error(_('AMQP server on %(hostname)s:%(port)d is '
|
||||
+ 'unreachable: %(err_str)s. Trying again in '
|
||||
+ '%(sleep_time)d seconds.') % log_info)
|
||||
time.sleep(sleep_time)
|
||||
|
||||
def ensure(self, error_callback, method, *args, **kwargs):
|
||||
@@ -512,7 +553,8 @@ class Connection(object):
|
||||
try:
|
||||
return method(*args, **kwargs)
|
||||
except (self.connection_errors, socket.timeout, IOError), e:
|
||||
- pass
|
||||
+ if error_callback:
|
||||
+ error_callback(e)
|
||||
except Exception, e:
|
||||
# NOTE(comstud): Unfortunately it's possible for amqplib
|
||||
# to return an error not covered by its transport
|
||||
@@ -522,8 +564,8 @@ class Connection(object):
|
||||
# and try to reconnect in this case.
|
||||
if 'timeout' not in str(e):
|
||||
raise
|
||||
- if error_callback:
|
||||
- error_callback(e)
|
||||
+ if error_callback:
|
||||
+ error_callback(e)
|
||||
self.reconnect()
|
||||
|
||||
def get_channel(self):
|
||||
|
@ -0,0 +1,27 @@
|
||||
require 'json'
|
||||
|
||||
def array_of_hash?(list)
|
||||
return false unless !list.empty? && list.class == Array
|
||||
list.each do |e|
|
||||
return false unless e.class == Hash
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:check_array_of_hash, :arity =>1, :type => :rvalue, :doc => "Check
|
||||
input String is a valid Array of Hash in JSON style") do |arg|
|
||||
if arg[0].class == String
|
||||
begin
|
||||
list = JSON.load(arg[0].gsub("'","\""))
|
||||
rescue JSON::ParserError
|
||||
raise Puppet::ParseError, "Syntax error: #{arg[0]} is invalid"
|
||||
else
|
||||
return arg[0] if array_of_hash?(list)
|
||||
end
|
||||
else
|
||||
raise Puppet::ParseError, "Syntax error: #{arg[0]} is not a String"
|
||||
end
|
||||
return ''
|
||||
end
|
||||
end
|
199
deployment/puppet/nova/lib/puppet/provider/nova.rb
Normal file
199
deployment/puppet/nova/lib/puppet/provider/nova.rb
Normal file
@ -0,0 +1,199 @@
|
||||
# Run test ie with: rspec spec/unit/provider/nova_spec.rb
|
||||
|
||||
require 'puppet/util/inifile'
|
||||
|
||||
class Puppet::Provider::Nova < Puppet::Provider
|
||||
|
||||
def self.conf_filename
|
||||
'/etc/nova/nova.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.nova_conf
|
||||
return @nova_conf if @nova_conf
|
||||
@nova_conf = Puppet::Util::IniConfig::File.new
|
||||
@nova_conf.read(conf_filename)
|
||||
@nova_conf
|
||||
end
|
||||
|
||||
def self.nova_credentials
|
||||
@nova_credentials ||= get_nova_credentials
|
||||
end
|
||||
|
||||
def nova_credentials
|
||||
self.class.nova_credentials
|
||||
end
|
||||
|
||||
def self.get_nova_credentials
|
||||
#needed keys for authentication
|
||||
auth_keys = ['auth_host', 'auth_port', 'auth_protocol',
|
||||
'admin_tenant_name', 'admin_user', 'admin_password']
|
||||
conf = nova_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. Nova types will not work if nova is not " +
|
||||
"correctly configured.")
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_auth_endpoint
|
||||
q = nova_credentials
|
||||
"#{q['auth_protocol']}://#{q['auth_host']}:#{q['auth_port']}/v2.0/"
|
||||
end
|
||||
|
||||
def self.auth_endpoint
|
||||
@auth_endpoint ||= get_auth_endpoint
|
||||
end
|
||||
|
||||
def self.auth_nova(*args)
|
||||
q = nova_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
|
||||
nova(args)
|
||||
end
|
||||
rescue Exception => e
|
||||
if (e.message =~ /\[Errno 111\] Connection refused/) or
|
||||
(e.message =~ /\(HTTP 400\)/)
|
||||
sleep 10
|
||||
withenv authenv do
|
||||
nova(args)
|
||||
end
|
||||
else
|
||||
raise(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def auth_nova(*args)
|
||||
self.class.auth_nova(args)
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@nova_conf = nil
|
||||
@nova_credentials = nil
|
||||
end
|
||||
|
||||
def self.str2hash(s)
|
||||
#parse string
|
||||
if s.include? "="
|
||||
k, v = s.split("=", 2)
|
||||
return {k.gsub(/'/, "") => v.gsub(/'/, "")}
|
||||
else
|
||||
return s.gsub(/'/, "")
|
||||
end
|
||||
end
|
||||
|
||||
def self.str2list(s)
|
||||
#parse string
|
||||
if s.include? ","
|
||||
if s.include? "="
|
||||
new = {}
|
||||
else
|
||||
new = []
|
||||
end
|
||||
s.split(",").each do |el|
|
||||
ret = str2hash(el.strip())
|
||||
if s.include? "="
|
||||
new.update(ret)
|
||||
else
|
||||
new.push(ret)
|
||||
end
|
||||
end
|
||||
return new
|
||||
else
|
||||
return str2hash(s.strip())
|
||||
end
|
||||
end
|
||||
|
||||
def self.cliout2list(output)
|
||||
#don't proceed with empty output
|
||||
if output.empty?
|
||||
return []
|
||||
end
|
||||
lines = []
|
||||
output.each_line do |line|
|
||||
#ignore lines starting with '+'
|
||||
if not line.match("^\\+")
|
||||
#split line at '|' and remove useless information
|
||||
line = line.gsub(/^\| /, "").gsub(/ \|$/, "").gsub(/[\n]+/, "")
|
||||
line = line.split("|").map do |el|
|
||||
el.strip().gsub(/^-$/, "")
|
||||
end
|
||||
#check every element for list
|
||||
line = line.map do |el|
|
||||
el = str2list(el)
|
||||
end
|
||||
lines.push(line)
|
||||
end
|
||||
end
|
||||
#create a list of hashes and return the list
|
||||
hash_list = []
|
||||
header = lines[0]
|
||||
lines[1..-1].each do |line|
|
||||
hash_list.push(Hash[header.zip(line)])
|
||||
end
|
||||
return hash_list
|
||||
end
|
||||
|
||||
def self.nova_aggregate_resources_ids
|
||||
#produce a list of hashes with Id=>Name pairs
|
||||
lines = []
|
||||
#run command
|
||||
cmd_output = auth_nova("aggregate-list")
|
||||
#parse output
|
||||
hash_list = cliout2list(cmd_output)
|
||||
#only interessted in Id and Name
|
||||
hash_list.map{ |e| e.delete("Availability Zone")}
|
||||
hash_list.map{ |e| e['Id'] = e['Id'].to_i}
|
||||
return hash_list
|
||||
end
|
||||
|
||||
def self.nova_aggregate_resources_get_name_by_id(name)
|
||||
#find the id by the given name
|
||||
nova_aggregate_resources_ids.each do |entry|
|
||||
if entry["Name"] == name
|
||||
return entry["Id"]
|
||||
end
|
||||
end
|
||||
#name not found
|
||||
return nil
|
||||
end
|
||||
|
||||
def self.nova_aggregate_resources_attr(id)
|
||||
#run command to get details for given Id
|
||||
cmd_output = auth_nova("aggregate-details", id)
|
||||
list = cliout2list(cmd_output)[0]
|
||||
if ! list["Hosts"].is_a?(Array)
|
||||
if list["Hosts"] == ""
|
||||
list["Hosts"] = []
|
||||
else
|
||||
list["Hosts"] = [ list["Hosts"] ]
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,157 @@
|
||||
require File.join(File.dirname(__FILE__), '..','..','..',
|
||||
'puppet/provider/nova')
|
||||
|
||||
Puppet::Type.type(:nova_aggregate).provide(
|
||||
:nova,
|
||||
:parent => Puppet::Provider::Nova
|
||||
) do
|
||||
|
||||
desc "Manage nova aggregations"
|
||||
|
||||
commands :nova => 'nova'
|
||||
|
||||
mk_resource_methods
|
||||
|
||||
def self.instances
|
||||
nova_aggregate_resources_ids().collect do |el|
|
||||
attrs = nova_aggregate_resources_attr(el['Id'])
|
||||
new(
|
||||
:ensure => :present,
|
||||
:name => attrs['Name'],
|
||||
:id => attrs['Id'],
|
||||
:availability_zone => attrs['Availability Zone'],
|
||||
:metadata => attrs['Metadata'],
|
||||
:hosts => attrs['Hosts']
|
||||
)
|
||||
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 destroy
|
||||
#delete hosts first
|
||||
if not @property_hash[:hosts].nil?
|
||||
@property_hash[:hosts].each do |h|
|
||||
auth_nova("aggregate-remove-host", name, h)
|
||||
end
|
||||
end
|
||||
#now delete aggregate
|
||||
auth_nova("aggregate-delete", name)
|
||||
@property_hash[:ensure] = :absent
|
||||
end
|
||||
|
||||
def create
|
||||
extras = Array.new
|
||||
#check for availability zone
|
||||
if not @resource[:availability_zone].nil? and not @resource[:availability_zone].empty?
|
||||
extras << "#{@resource[:availability_zone]}"
|
||||
end
|
||||
#run the command
|
||||
result = auth_nova("aggregate-create", resource[:name], extras)
|
||||
|
||||
#get Id by Name
|
||||
id = self.class.nova_aggregate_resources_get_name_by_id(resource[:name])
|
||||
|
||||
@property_hash = {
|
||||
:ensure => :present,
|
||||
:name => resource[:name],
|
||||
:id => id,
|
||||
:availability_zone => resource[:availability_zone]
|
||||
}
|
||||
|
||||
#add metadata
|
||||
if not @resource[:metadata].nil? and not @resource[:metadata].empty?
|
||||
@resource[:metadata].each do |key, value|
|
||||
set_metadata_helper(id, key, value)
|
||||
end
|
||||
@property_hash[:metadata] = resource[:metadata]
|
||||
end
|
||||
|
||||
#add hosts - This throws an error if the host is already attached to another aggregate!
|
||||
if not @resource[:hosts].nil? and not @resource[:hosts].empty?
|
||||
@resource[:hosts].each do |host|
|
||||
auth_nova("aggregate-add-host", id, "#{host}")
|
||||
end
|
||||
@property_hash[:hosts] = resource[:hosts]
|
||||
end
|
||||
end
|
||||
|
||||
def hosts=(val)
|
||||
#get current hosts
|
||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
||||
#remove all hosts which are not in new value list
|
||||
attrs['Hosts'].each do |h|
|
||||
if not val.include? h
|
||||
auth_nova("aggregate-remove-host", id, "#{h}")
|
||||
end
|
||||
end
|
||||
|
||||
#add hosts from the value list
|
||||
val.each do |h|
|
||||
if not attrs['Hosts'].include? h
|
||||
auth_nova("aggregate-add-host", id, "#{h}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_metadata_helper(agg_id, key, value)
|
||||
auth_nova("aggregate-set-metadata", agg_id, "#{key}=#{value}")
|
||||
end
|
||||
|
||||
def metadata
|
||||
#get current metadata
|
||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
||||
#just ignore the availability_zone. that's handled directly by nova
|
||||
attrs['Metadata'].delete('availability_zone')
|
||||
return attrs['Metadata']
|
||||
end
|
||||
|
||||
def metadata=(val)
|
||||
#get current metadata
|
||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
||||
#get keys which are in current metadata but not in val. Make sure it has data first!
|
||||
if attrs['Metadata'].length > 0
|
||||
obsolete_keys = attrs['Metadata'].keys - val.keys
|
||||
end
|
||||
# clear obsolete keys. If there are any!
|
||||
if obsolete_keys
|
||||
obsolete_keys.each do |key|
|
||||
if not key.include? 'availability_zone'
|
||||
auth_nova("aggregate-set-metadata", id, "#{key}")
|
||||
end
|
||||
end
|
||||
#handle keys (with obsolete keys)
|
||||
new_keys = val.keys - obsolete_keys
|
||||
else
|
||||
#handle keys (without obsolete keys)
|
||||
new_keys = val.keys
|
||||
end
|
||||
#set new metadata if value changed
|
||||
new_keys.each do |key|
|
||||
if val[key] != attrs['Metadata'][key.to_s]
|
||||
value = val[key]
|
||||
set_metadata_helper(id, key, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def availability_zone=(val)
|
||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
||||
auth_nova("aggregate-set-metadata", id, "availability_zone=#{val}")
|
||||
end
|
||||
|
||||
end
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -13,7 +13,7 @@ Puppet::Type.type(:nova_floating).provide(:nova_manage) do
|
||||
end
|
||||
|
||||
def create
|
||||
nova_manage("floating", "create", resource[:network])
|
||||
nova_manage("floating", "create", '--pool', resource[:pool], resource[:network])
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -1,77 +0,0 @@
|
||||
require 'openstack'
|
||||
require 'netaddr'
|
||||
|
||||
Puppet::Type.type(:nova_floating_range).provide :nova_manage do
|
||||
desc 'Create nova floating range'
|
||||
|
||||
commands :nova_manage => 'nova-manage'
|
||||
|
||||
def exists?
|
||||
@resource[:ensure] = 'present' unless @resource[:ensure]
|
||||
|
||||
if @resource[:ensure] == :absent
|
||||
operate_range.any?
|
||||
else
|
||||
operate_range.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
mixed_range.each do |ip|
|
||||
connect.create_floating_ips_bulk :ip_range => ip, :pool => @resource[:pool]
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
mixed_range.each do |ip|
|
||||
nova_manage("floating", "delete", ip )
|
||||
end
|
||||
end
|
||||
|
||||
# Create range in cidr, including first and last ip
|
||||
# Nova will create this range, excluding network and broadcast IPs
|
||||
def mixed_range
|
||||
range = []
|
||||
NetAddr.merge(operate_range).each do |cidr|
|
||||
tmp_range = NetAddr::CIDR.create(cidr).enumerate
|
||||
range << tmp_range.first.to_s
|
||||
range << tmp_range.last.to_s
|
||||
end
|
||||
|
||||
range.uniq!
|
||||
|
||||
range += NetAddr.merge(operate_range).delete_if{ |part| part =~ /\/3[12]/}
|
||||
end
|
||||
|
||||
# Calculate exist IP and current range
|
||||
def operate_range
|
||||
exist_range = []
|
||||
connect.get_floating_ips_bulk.each do |element|
|
||||
exist_range << element.address
|
||||
end
|
||||
if @resource[:ensure] == :absent
|
||||
ip_range & exist_range
|
||||
else
|
||||
ip_range - exist_range
|
||||
end
|
||||
end
|
||||
|
||||
# Create array of IPs from range
|
||||
def ip_range
|
||||
ip = @resource[:name].split('-')
|
||||
ip_range = NetAddr.range NetAddr::CIDR.create(ip.first), NetAddr::CIDR.create(ip.last)
|
||||
ip_range.unshift(ip.first).push(ip.last)
|
||||
end
|
||||
|
||||
# Connect to OpenStack
|
||||
def connect
|
||||
@connect ||= OpenStack::Connection.create :username => @resource[:username],
|
||||
:api_key => @resource[:api_key],
|
||||
:auth_method => @resource[:auth_method],
|
||||
:auth_url => @resource[:auth_url],
|
||||
:authtenant_name => @resource[:authtenant_name],
|
||||
:service_type => @resource[:service_type],
|
||||
:retries => @resource[:api_retries],
|
||||
:is_debug => Puppet[:debug]
|
||||
end
|
||||
end
|
@ -27,7 +27,6 @@ Puppet::Type.type(:nova_network).provide(:nova_manage) do
|
||||
{
|
||||
# this needs to be converted from a project name to an id
|
||||
:project => '--project_id',
|
||||
:dns1 => '--dns1',
|
||||
:dns2 => '--dns2',
|
||||
:gateway => '--gateway',
|
||||
:bridge => '--bridge',
|
||||
|
110
deployment/puppet/nova/lib/puppet/type/nova_aggregate.rb
Normal file
110
deployment/puppet/nova/lib/puppet/type/nova_aggregate.rb
Normal file
@ -0,0 +1,110 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2014 Deutsche Telekom AG
|
||||
#
|
||||
# Author: Thomas Bechtold <t.bechtold@telekom.de>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# nova_aggregate type
|
||||
#
|
||||
# == Parameters
|
||||
# [*name*]
|
||||
# Name for the new aggregate
|
||||
# Required
|
||||
#
|
||||
# [*availability_zone*]
|
||||
# The availability zone. ie "zone1"
|
||||
# Optional
|
||||
#
|
||||
# [*metadata*]
|
||||
# String with key/value pairs. ie "key=value,key=value"
|
||||
# Optional
|
||||
#
|
||||
# [*hosts*]
|
||||
# A comma seperated list with hosts or a single host. ie "host1,host2"
|
||||
# Optional
|
||||
#
|
||||
|
||||
require 'puppet'
|
||||
|
||||
Puppet::Type.newtype(:nova_aggregate) do
|
||||
|
||||
@doc = "Manage creation of nova aggregations."
|
||||
|
||||
ensurable
|
||||
|
||||
autorequire(:nova_config) do
|
||||
['auth_host', 'auth_port', 'auth_protocol', 'admin_tenant_name', 'admin_user', 'admin_password']
|
||||
end
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'Name for the new aggregate'
|
||||
validate do |value|
|
||||
if not value.is_a? String
|
||||
raise ArgumentError, "name parameter must be a String"
|
||||
end
|
||||
unless value =~ /[a-z0-9]+/
|
||||
raise ArgumentError, "#{value} is not a valid name"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:id) do
|
||||
desc 'The unique Id of the aggregate'
|
||||
validate do |v|
|
||||
raise ArgumentError, 'This is a read only property'
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:availability_zone) do
|
||||
desc 'The availability zone of the aggregate'
|
||||
validate do |value|
|
||||
if not value.is_a? String
|
||||
raise ArgumentError, "availability zone must be a String"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:metadata) do
|
||||
desc 'The metadata of the aggregate'
|
||||
#convert DSL/string form to internal form which is a single hash
|
||||
munge do |value|
|
||||
internal = Hash.new
|
||||
value.split(",").map{|el| el.strip()}.each do |pair|
|
||||
key, value = pair.split("=", 2)
|
||||
internal[key.strip()] = value.strip()
|
||||
end
|
||||
return internal
|
||||
end
|
||||
|
||||
validate do |value|
|
||||
value.split(",").each do |kv|
|
||||
raise ArgumentError, "Key/value pairs must be separated by an =" unless value.include?("=")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:hosts) do
|
||||
desc 'Single host or comma seperated list of hosts'
|
||||
#convert DSL/string form to internal form
|
||||
munge do |value|
|
||||
return value.split(",").map{|el| el.strip()}
|
||||
end
|
||||
end
|
||||
|
||||
validate do
|
||||
raise ArgumentError, 'Name type must be set' unless self[:name]
|
||||
end
|
||||
|
||||
end
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -3,11 +3,7 @@ Puppet::Type.newtype(:nova_config) do
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
validate do |value|
|
||||
unless value =~ /\S+\/\S+/
|
||||
fail("Invalid nova_config #{value}, entries without sections are no longer supported, please add an explicit section (probably DEFAULT) to all nova_config resources")
|
||||
end
|
||||
end
|
||||
newvalues(/\S+\/\S+/)
|
||||
end
|
||||
|
||||
newproperty(:value) do
|
||||
@ -43,13 +39,4 @@ Puppet::Type.newtype(:nova_config) do
|
||||
|
||||
defaultto false
|
||||
end
|
||||
|
||||
validate do
|
||||
if self[:ensure] == :present
|
||||
if self[:value].nil?
|
||||
raise Puppet::Error, "Property value must be set for #{self[:name]} when ensure is present"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -5,8 +5,14 @@ Puppet::Type.newtype(:nova_floating) do
|
||||
ensurable
|
||||
|
||||
newparam(:network, :namevar => true) do
|
||||
desc "Network (ie, 192.168.1.0/24 or 192.168.1.128/25 etc.)"
|
||||
desc "Network (ie, 192.168.1.0/24 or 192.168.1.128/25 etc.)"
|
||||
newvalues(/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$/)
|
||||
end
|
||||
|
||||
newparam(:pool) do
|
||||
desc "Floating IP pool name. Default: 'nova'"
|
||||
defaultto :nova
|
||||
newvalues(/^.{1,255}$/)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,88 +0,0 @@
|
||||
Puppet::Type.newtype(:nova_floating_range) do
|
||||
|
||||
@doc = 'Manage creation/deletion of nova floating ip ranges.'
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'IP range ("192.168.1.1-192.168.1.55")'
|
||||
|
||||
validate do |value|
|
||||
raise Puppet::Error, " #{value} does not look like IP range" unless value =~ /^(\d{1,3}\.){3}\d{1,3}-(\d{1,3}\.){3}\d{1,3}$/
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:pool) do
|
||||
desc 'Pool ranges'
|
||||
|
||||
defaultto 'nova'
|
||||
end
|
||||
|
||||
newparam(:interface) do
|
||||
# I don't know how use it
|
||||
desc 'Interface for floating IP'
|
||||
end
|
||||
|
||||
newparam(:username) do
|
||||
desc 'authorization user'
|
||||
|
||||
munge do |value|
|
||||
String value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:api_key) do
|
||||
desc 'authorization key'
|
||||
|
||||
munge do |value|
|
||||
String value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:auth_method) do
|
||||
desc 'authorization password'
|
||||
|
||||
munge do |value|
|
||||
String value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:auth_url) do
|
||||
desc 'URL to keystone authorization http://192.168.1.1:5000/v2.0/'
|
||||
|
||||
validate do |value|
|
||||
raise Puppet::Error, "#{value} does not look like URL" unless value =~ /^https?:\/\/\S+:\d{1,5}\/v[\d\.]{1,5}\//
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:authtenant_name) do
|
||||
desc 'Tenant name'
|
||||
|
||||
munge do |value|
|
||||
String value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:api_retries) do
|
||||
desc 'number of API reconnect retries'
|
||||
|
||||
validate do |value|
|
||||
raise Puppet::Error, "#{value} does not look like numeric" unless value.is_a?(Integer) || value =~ /^\d+$/
|
||||
end
|
||||
|
||||
munge do |value|
|
||||
Integer value
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:service_type) do
|
||||
desc 'Connection type :service_type parameter to "compute", "object-store", "volume" or "network" (defaults to "compute")'
|
||||
|
||||
defaultto 'compute'
|
||||
|
||||
munge do |value|
|
||||
String value
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -34,12 +34,7 @@ Puppet::Type.newtype(:nova_network) do
|
||||
newparam(:gateway) do
|
||||
end
|
||||
|
||||
newparam(:dns1) do
|
||||
desc 'first dns server'
|
||||
end
|
||||
|
||||
newparam(:dns2) do
|
||||
desc 'second dns server'
|
||||
end
|
||||
|
||||
newparam(:vlan_start) do
|
||||
|
@ -19,28 +19,28 @@
|
||||
# (optional) Whether the nova api package will be installed
|
||||
# Defaults to 'present'
|
||||
#
|
||||
# [*auth_strategy*]
|
||||
# (DEPRECATED) Does nothing and will be removed in Icehouse
|
||||
# Defaults to false
|
||||
#
|
||||
# [*auth_host*]
|
||||
# (optional) The IP of the server running keystone
|
||||
# (optional) DEPRECATED. The IP of the server running keystone
|
||||
# Defaults to '127.0.0.1'
|
||||
#
|
||||
# [*auth_port*]
|
||||
# (optional) The port to use when authenticating against Keystone
|
||||
# (optional) DEPRECATED. The port to use when authenticating against Keystone
|
||||
# Defaults to 35357
|
||||
#
|
||||
# [*auth_protocol*]
|
||||
# (optional) The protocol to use when authenticating against Keystone
|
||||
# (optional) DEPRECATED. The protocol to use when authenticating against Keystone
|
||||
# Defaults to 'http'
|
||||
#
|
||||
# [*auth_uri*]
|
||||
# (optional) The uri of a Keystone service to authenticate against
|
||||
# (optional) Complete public Identity API endpoint.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*identity_uri*]
|
||||
# (optional) Complete admin Identity API endpoint.
|
||||
# Defaults to: false
|
||||
#
|
||||
# [*auth_admin_prefix*]
|
||||
# (optional) Prefix to prepend at the beginning of the keystone path
|
||||
# (optional) DEPRECATED. Prefix to prepend at the beginning of the keystone path
|
||||
# Defaults to false
|
||||
#
|
||||
# [*auth_version*]
|
||||
@ -68,6 +68,10 @@
|
||||
# (optional) A comma separated list of apis to enable
|
||||
# Defaults to 'ec2,osapi_compute,metadata'
|
||||
#
|
||||
# [*keystone_ec2_url*]
|
||||
# (optional) The keystone url where nova should send requests for ec2tokens
|
||||
# Defaults to false
|
||||
#
|
||||
# [*volume_api_class*]
|
||||
# (optional) The name of the class that nova will use to access volumes. Cinder is the only option.
|
||||
# Defaults to 'nova.volume.cinder.API'
|
||||
@ -81,13 +85,18 @@
|
||||
# (optional) Number of workers for OpenStack API service
|
||||
# Defaults to $::processorcount
|
||||
#
|
||||
# [*ec2_workers*]
|
||||
# (optional) Number of workers for EC2 service
|
||||
# Defaults to $::processorcount
|
||||
#
|
||||
# [*metadata_workers*]
|
||||
# (optional) Number of workers for metadata service
|
||||
# Defaults to $::processorcount
|
||||
#
|
||||
# [*conductor_workers*]
|
||||
# (optional) Number of workers for OpenStack Conductor service
|
||||
# Defaults to $::processorcount
|
||||
# (optional) DEPRECATED. Use workers parameter of nova::conductor
|
||||
# Class instead.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*sync_db*]
|
||||
# (optional) Run nova-manage db sync on api nodes after installing the package.
|
||||
@ -97,6 +106,12 @@
|
||||
# (optional) Shared secret to validate proxies Neutron metadata requests
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*pci_alias*]
|
||||
# (optional) Pci passthrough for controller:
|
||||
# Defaults to undef
|
||||
# Example
|
||||
# "[ {'vendor_id':'1234', 'product_id':'5678', 'name':'default'}, {...} ]"
|
||||
#
|
||||
# [*ratelimits*]
|
||||
# (optional) A string that is a semicolon-separated list of 5-tuples.
|
||||
# See http://docs.openstack.org/trunk/config-reference/content/configuring-compute-API.html
|
||||
@ -107,58 +122,84 @@
|
||||
# (optional) The rate limiting factory to use
|
||||
# Defaults to 'nova.api.openstack.compute.limits:RateLimitingMiddleware.factory'
|
||||
#
|
||||
# [*osapi_v3*]
|
||||
# (optional) Enable or not Nova API v3
|
||||
# Defaults to false
|
||||
#
|
||||
# [*validate*]
|
||||
# (optional) Whether to validate the service is working after any service refreshes
|
||||
# Defaults to false
|
||||
#
|
||||
# [*validation_options*]
|
||||
# (optional) Service validation options
|
||||
# Should be a hash of options defined in openstacklib::service_validation
|
||||
# If empty, defaults values are taken from openstacklib function.
|
||||
# Default command list nova flavors.
|
||||
# Require validate set at True.
|
||||
# Example:
|
||||
# nova::api::validation_options:
|
||||
# nova-api:
|
||||
# command: check_nova.py
|
||||
# path: /usr/bin:/bin:/usr/sbin:/sbin
|
||||
# provider: shell
|
||||
# tries: 5
|
||||
# try_sleep: 10
|
||||
# Defaults to {}
|
||||
#
|
||||
class nova::api(
|
||||
$admin_password,
|
||||
$enabled = false,
|
||||
$manage_service = true,
|
||||
$ensure_package = 'present',
|
||||
$auth_strategy = undef,
|
||||
$auth_host = '127.0.0.1',
|
||||
$auth_port = 35357,
|
||||
$auth_protocol = 'http',
|
||||
$auth_uri = false,
|
||||
$auth_admin_prefix = false,
|
||||
$identity_uri = false,
|
||||
$auth_version = false,
|
||||
$admin_tenant_name = 'services',
|
||||
$admin_user = 'nova',
|
||||
$api_bind_address = '0.0.0.0',
|
||||
$metadata_listen = '0.0.0.0',
|
||||
$enabled_apis = 'ec2,osapi_compute,metadata',
|
||||
$keystone_ec2_url = false,
|
||||
$volume_api_class = 'nova.volume.cinder.API',
|
||||
$use_forwarded_for = false,
|
||||
$osapi_compute_workers = $::processorcount,
|
||||
$ec2_workers = $::processorcount,
|
||||
$metadata_workers = $::processorcount,
|
||||
$conductor_workers = $::processorcount,
|
||||
$sync_db = true,
|
||||
$neutron_metadata_proxy_shared_secret = undef,
|
||||
$osapi_v3 = false,
|
||||
$pci_alias = undef,
|
||||
$ratelimits = undef,
|
||||
$ratelimits_factory =
|
||||
'nova.api.openstack.compute.limits:RateLimitingMiddleware.factory',
|
||||
$validate = false,
|
||||
$validation_options = {},
|
||||
# DEPRECATED PARAMETER
|
||||
$workers = undef,
|
||||
$auth_protocol = 'http',
|
||||
$auth_port = 35357,
|
||||
$auth_host = '127.0.0.1',
|
||||
$auth_admin_prefix = false,
|
||||
$conductor_workers = undef,
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
require keystone::python
|
||||
include cinder::client
|
||||
include ::nova::db
|
||||
include ::nova::params
|
||||
include ::nova::policy
|
||||
require ::keystone::python
|
||||
include ::cinder::client
|
||||
|
||||
Package<| title == 'nova-api' |> -> Nova_paste_api_ini<| |>
|
||||
|
||||
Package<| title == 'nova-common' |> -> Class['nova::api']
|
||||
Package<| title == 'nova-common' |> -> Class['nova::policy']
|
||||
|
||||
Nova_paste_api_ini<| |> ~> Exec['post-nova_config']
|
||||
|
||||
Nova_paste_api_ini<| |> ~> Service['nova-api']
|
||||
Class['nova::policy'] ~> Service['nova-api']
|
||||
|
||||
if $auth_strategy {
|
||||
warning('The auth_strategy parameter is deprecated and has no effect.')
|
||||
}
|
||||
|
||||
if $workers {
|
||||
warning('The workers parameter is deprecated, use osapi_compute_workers instead.')
|
||||
$osapi_compute_workers_real = $workers
|
||||
} else {
|
||||
$osapi_compute_workers_real = $osapi_compute_workers
|
||||
if $conductor_workers {
|
||||
warning('The conductor_workers parameter is deprecated and has no effect. Use workers parameter of nova::conductor class instead.')
|
||||
}
|
||||
|
||||
nova::generic_service { 'api':
|
||||
@ -177,29 +218,37 @@ class nova::api(
|
||||
'DEFAULT/osapi_compute_listen': value => $api_bind_address;
|
||||
'DEFAULT/metadata_listen': value => $metadata_listen;
|
||||
'DEFAULT/osapi_volume_listen': value => $api_bind_address;
|
||||
'DEFAULT/osapi_compute_workers': value => $osapi_compute_workers_real;
|
||||
'DEFAULT/osapi_compute_workers': value => $osapi_compute_workers;
|
||||
'DEFAULT/ec2_workers': value => $ec2_workers;
|
||||
'DEFAULT/metadata_workers': value => $metadata_workers;
|
||||
'conductor/workers': value => $conductor_workers;
|
||||
'DEFAULT/use_forwarded_for': value => $use_forwarded_for;
|
||||
'osapi_v3/enabled': value => $osapi_v3;
|
||||
}
|
||||
|
||||
if ($neutron_metadata_proxy_shared_secret){
|
||||
nova_config {
|
||||
'DEFAULT/service_neutron_metadata_proxy': value => true;
|
||||
'DEFAULT/neutron_metadata_proxy_shared_secret':
|
||||
'neutron/service_metadata_proxy': value => true;
|
||||
'neutron/metadata_proxy_shared_secret':
|
||||
value => $neutron_metadata_proxy_shared_secret;
|
||||
}
|
||||
} else {
|
||||
nova_config {
|
||||
'DEFAULT/service_neutron_metadata_proxy': value => false;
|
||||
'DEFAULT/neutron_metadata_proxy_shared_secret': ensure => absent;
|
||||
'neutron/service_metadata_proxy': value => false;
|
||||
'neutron/metadata_proxy_shared_secret': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $auth_uri {
|
||||
nova_config { 'keystone_authtoken/auth_uri': value => $auth_uri; }
|
||||
$auth_uri_real = $auth_uri
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/auth_uri': value => "${auth_protocol}://${auth_host}:5000/"; }
|
||||
$auth_uri_real = "${auth_protocol}://${auth_host}:5000/"
|
||||
}
|
||||
nova_config { 'keystone_authtoken/auth_uri': value => $auth_uri_real; }
|
||||
|
||||
if $identity_uri {
|
||||
nova_config { 'keystone_authtoken/identity_uri': value => $identity_uri; }
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/identity_uri': ensure => absent; }
|
||||
}
|
||||
|
||||
if $auth_version {
|
||||
@ -208,23 +257,62 @@ class nova::api(
|
||||
nova_config { 'keystone_authtoken/auth_version': ensure => absent; }
|
||||
}
|
||||
|
||||
# if both auth_uri and identity_uri are set we skip these deprecated settings entirely
|
||||
if !$auth_uri or !$identity_uri {
|
||||
|
||||
if $auth_host {
|
||||
warning('The auth_host parameter is deprecated. Please use auth_uri and identity_uri instead.')
|
||||
nova_config { 'keystone_authtoken/auth_host': value => $auth_host; }
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/auth_host': ensure => absent; }
|
||||
}
|
||||
|
||||
if $auth_port {
|
||||
warning('The auth_port parameter is deprecated. Please use auth_uri and identity_uri instead.')
|
||||
nova_config { 'keystone_authtoken/auth_port': value => $auth_port; }
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/auth_port': ensure => absent; }
|
||||
}
|
||||
|
||||
if $auth_protocol {
|
||||
warning('The auth_protocol parameter is deprecated. Please use auth_uri and identity_uri instead.')
|
||||
nova_config { 'keystone_authtoken/auth_protocol': value => $auth_protocol; }
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/auth_protocol': ensure => absent; }
|
||||
}
|
||||
|
||||
if $auth_admin_prefix {
|
||||
warning('The auth_admin_prefix parameter is deprecated. Please use auth_uri and identity_uri instead.')
|
||||
validate_re($auth_admin_prefix, '^(/.+[^/])?$')
|
||||
nova_config {
|
||||
'keystone_authtoken/auth_admin_prefix': value => $auth_admin_prefix;
|
||||
}
|
||||
} else {
|
||||
nova_config { 'keystone_authtoken/auth_admin_prefix': ensure => absent; }
|
||||
}
|
||||
|
||||
} else {
|
||||
nova_config {
|
||||
'keystone_authtoken/auth_host': ensure => absent;
|
||||
'keystone_authtoken/auth_port': ensure => absent;
|
||||
'keystone_authtoken/auth_protocol': ensure => absent;
|
||||
'keystone_authtoken/auth_admin_prefix': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
nova_config {
|
||||
'keystone_authtoken/auth_host': value => $auth_host;
|
||||
'keystone_authtoken/auth_port': value => $auth_port;
|
||||
'keystone_authtoken/auth_protocol': value => $auth_protocol;
|
||||
'keystone_authtoken/admin_tenant_name': value => $admin_tenant_name;
|
||||
'keystone_authtoken/admin_user': value => $admin_user;
|
||||
'keystone_authtoken/admin_password': value => $admin_password, secret => true;
|
||||
}
|
||||
|
||||
if $auth_admin_prefix {
|
||||
validate_re($auth_admin_prefix, '^(/.+[^/])?$')
|
||||
if $keystone_ec2_url {
|
||||
nova_config {
|
||||
'keystone_authtoken/auth_admin_prefix': value => $auth_admin_prefix;
|
||||
'DEFAULT/keystone_ec2_url': value => $keystone_ec2_url;
|
||||
}
|
||||
} else {
|
||||
nova_config {
|
||||
'keystone_authtoken/auth_admin_prefix': ensure => absent;
|
||||
'DEFAULT/keystone_ec2_url': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +346,9 @@ class nova::api(
|
||||
# Added arg and if statement prevents this from being run
|
||||
# where db is not active i.e. the compute
|
||||
if $sync_db {
|
||||
Package<| title == 'nova-api' |> -> Exec['nova-db-sync']
|
||||
Package<| title == $::nova::params::api_package_name |> ~> Exec['nova-db-sync']
|
||||
Package<| title == $::nova::params::common_package_name |> ~> Exec['nova-db-sync']
|
||||
|
||||
exec { 'nova-db-sync':
|
||||
command => '/usr/bin/nova-manage db sync',
|
||||
refreshonly => true,
|
||||
@ -278,4 +368,19 @@ class nova::api(
|
||||
'filter:authtoken/auth_admin_prefix': ensure => absent;
|
||||
}
|
||||
|
||||
if $pci_alias {
|
||||
nova_config {
|
||||
'DEFAULT/pci_alias': value => check_array_of_hash($pci_alias);
|
||||
}
|
||||
}
|
||||
|
||||
if $validate {
|
||||
$defaults = {
|
||||
'nova-api' => {
|
||||
'command' => "nova --os-auth-url ${auth_uri_real} --os-tenant-name ${admin_tenant_name} --os-username ${admin_user} --os-password ${admin_password} flavor-list",
|
||||
}
|
||||
}
|
||||
$validation_options_hash = merge ($defaults, $validation_options)
|
||||
create_resources('openstacklib::service_validation', $validation_options_hash, {'subscribe' => 'Service[nova-api]'})
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -16,9 +16,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# The nova::cells class installs the Nova Cells
|
||||
# == Class: nova::cells
|
||||
#
|
||||
# Installs the Nova Cells
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# == Parameters
|
||||
# [*enabled*]
|
||||
# Use Nova Cells or not
|
||||
# Defaults to 'False'
|
||||
@ -35,6 +38,10 @@
|
||||
# Cells communication driver to use
|
||||
# Defaults to 'nova.cells.rpc_driver.CellsRPCDriver'
|
||||
#
|
||||
# [*ensure_package*]
|
||||
# Desired ensure state of packages.
|
||||
# Defaults to present
|
||||
#
|
||||
# [*instance_updated_at_threshold*]
|
||||
# Number of seconds after an instance was updated or deleted to continue to update cells
|
||||
# Defaults to '3600'
|
||||
@ -133,7 +140,6 @@
|
||||
# It might be used by some cell scheduling code in the future
|
||||
# Defaults to '1.0'
|
||||
#
|
||||
|
||||
class nova::cells (
|
||||
$bandwidth_update_interval = '600',
|
||||
$call_timeout = '60',
|
||||
@ -166,16 +172,16 @@ class nova::cells (
|
||||
$weight_scale = '1.0'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
case $cell_type {
|
||||
'parent': {
|
||||
nova_config { 'DEFAULT/compute_api_class': value => 'nova.compute.cells_api.ComputeCellsAPI' }
|
||||
nova_config { 'DEFAULT/cell_type': value => 'api' }
|
||||
nova_config { 'cells/cell_type': value => 'api' }
|
||||
}
|
||||
'child': {
|
||||
nova_config { 'DEFAULT/quota_driver': value => 'nova.quota.NoopQuotaDriver' }
|
||||
nova_config { 'DEFAULT/cell_type': value => 'compute' }
|
||||
nova_config { 'cells/cell_type': value => 'compute' }
|
||||
}
|
||||
default: { fail("Unsupported cell_type parameter value: '${cell_type}'. Should be 'parent' or 'child'.") }
|
||||
}
|
||||
@ -217,11 +223,11 @@ class nova::cells (
|
||||
@@nova::manage::cells { $cell_name:
|
||||
cell_type => $cell_type,
|
||||
cell_parent_name => $cell_parent_name,
|
||||
rabbit_username => $::nova::init::rabbit_userid,
|
||||
rabbit_password => $::nova::init::rabbit_password,
|
||||
rabbit_hosts => $::nova::init::rabbit_hosts,
|
||||
rabbit_port => $::nova::init::rabbit_port,
|
||||
rabbit_virtual_host => $::nova::init::virtual_host,
|
||||
rabbit_username => $::nova::rabbit_userid,
|
||||
rabbit_password => $::nova::rabbit_password,
|
||||
rabbit_hosts => $::nova::rabbit_hosts,
|
||||
rabbit_port => $::nova::rabbit_port,
|
||||
rabbit_virtual_host => $::nova::rabbit_virtual_host,
|
||||
weight_offset => $weight_offset,
|
||||
weight_scale => $weight_scale,
|
||||
before => Service['cells']
|
||||
|
@ -22,7 +22,7 @@ class nova::cert(
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
nova::generic_service { 'cert':
|
||||
enabled => $enabled,
|
||||
|
@ -14,6 +14,7 @@ class nova::client(
|
||||
|
||||
package { 'python-novaclient':
|
||||
ensure => $ensure,
|
||||
tag => ['openstack'],
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,10 @@
|
||||
# (optional) Whether to enable the nova-compute service
|
||||
# Defaults to false
|
||||
#
|
||||
# [*heal_instance_info_cache_interval*]
|
||||
# (optional) Controls how often the instance info should be updated.
|
||||
# Defaults to '60' , to disable you can set the value to zero.
|
||||
#
|
||||
# [*manage_service*]
|
||||
# (optional) Whether to start/stop the service
|
||||
# Defaults to true
|
||||
@ -38,7 +42,11 @@
|
||||
#
|
||||
# [*vncproxy_path*]
|
||||
# (optional) The path at the end of the uri for communication with the VNC proxy server
|
||||
# Defaults to './vnc_auto.html'
|
||||
# Defaults to '/vnc_auto.html'
|
||||
#
|
||||
# [*vnc_keymap*]
|
||||
# (optional) The keymap to use with VNC (ls -alh /usr/share/qemu/keymaps to list available keymaps)
|
||||
# Defaults to 'en-us'
|
||||
#
|
||||
# [*force_config_drive*]
|
||||
# (optional) Whether to force the config drive to be attached to all VMs
|
||||
@ -65,9 +73,23 @@
|
||||
# Time period must be hour, day, month or year
|
||||
# Defaults to 'month'
|
||||
#
|
||||
# [*force_raw_images*]
|
||||
# (optional) Force backing images to raw format.
|
||||
# Defaults to true
|
||||
#
|
||||
# [*reserved_host_memory*]
|
||||
# Reserved host memory
|
||||
# The amount of memory in MB reserved for the host.
|
||||
# Defaults to '512'
|
||||
#
|
||||
# [*compute_manager*]
|
||||
# Compute manager
|
||||
# The driver that will manage the running instances.
|
||||
# Defaults to nova.compute.manager.ComputeManager
|
||||
#
|
||||
# [*default_availability_zone*]
|
||||
# (optional) Default compute node availability zone.
|
||||
# Defaults to undef
|
||||
# Defaults to nova
|
||||
#
|
||||
# [*default_schedule_zone*]
|
||||
# (optional) Availability zone to use when user doesn't specify one.
|
||||
@ -75,7 +97,14 @@
|
||||
#
|
||||
# [*internal_service_availability_zone*]
|
||||
# (optional) The availability zone to show internal services under.
|
||||
# Defaults to internal
|
||||
#
|
||||
# [*pci_passthrough*]
|
||||
# (optional) Pci passthrough hash in format of:
|
||||
# Defaults to undef
|
||||
# Example
|
||||
# "[ { 'vendor_id':'1234','product_id':'5678' },
|
||||
# { 'vendor_id':'4321','product_id':'8765','physical_network':'default' } ] "
|
||||
#
|
||||
class nova::compute (
|
||||
$enabled = false,
|
||||
@ -87,39 +116,47 @@ class nova::compute (
|
||||
$vncproxy_protocol = 'http',
|
||||
$vncproxy_port = '6080',
|
||||
$vncproxy_path = '/vnc_auto.html',
|
||||
$vnc_keymap = 'en-us',
|
||||
$force_config_drive = false,
|
||||
$virtio_nic = false,
|
||||
$neutron_enabled = true,
|
||||
$network_device_mtu = undef,
|
||||
$instance_usage_audit = false,
|
||||
$instance_usage_audit_period = 'month',
|
||||
$default_availability_zone = undef,
|
||||
$force_raw_images = true,
|
||||
$reserved_host_memory = '512',
|
||||
$compute_manager = 'nova.compute.manager.ComputeManager',
|
||||
$default_availability_zone = 'nova',
|
||||
$default_schedule_zone = undef,
|
||||
$internal_service_availability_zone = undef,
|
||||
$internal_service_availability_zone = 'internal',
|
||||
$heal_instance_info_cache_interval = '60',
|
||||
$pci_passthrough = undef,
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include stdlib
|
||||
include ::nova::params
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/reserved_host_memory_mb': value => $reserved_host_memory;
|
||||
'DEFAULT/compute_manager': value => $compute_manager;
|
||||
'DEFAULT/heal_instance_info_cache_interval': value => $heal_instance_info_cache_interval;
|
||||
}
|
||||
|
||||
if ($vnc_enabled) {
|
||||
if ($vncproxy_host) {
|
||||
$vncproxy_base_url = "${vncproxy_protocol}://${vncproxy_host}:${vncproxy_port}${vncproxy_path}"
|
||||
# config for vnc proxy
|
||||
nova_config {
|
||||
'DEFAULT/novncproxy_base_url': value => $vncproxy_base_url;
|
||||
}
|
||||
}
|
||||
include ::nova::vncproxy::common
|
||||
}
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/vnc_enabled': value => $vnc_enabled;
|
||||
'DEFAULT/vncserver_proxyclient_address': value => $vncserver_proxyclient_address;
|
||||
'DEFAULT/vnc_keymap': value => $vnc_keymap;
|
||||
}
|
||||
|
||||
if $neutron_enabled != true {
|
||||
# Install bridge-utils if we use nova-network
|
||||
ensure_packages('bridge-utils')
|
||||
Package <| title == 'bridge-utils' |> -> Nova::Generic_service['compute']
|
||||
package { 'bridge-utils':
|
||||
ensure => present,
|
||||
before => Nova::Generic_service['compute'],
|
||||
}
|
||||
}
|
||||
|
||||
nova::generic_service { 'compute':
|
||||
@ -164,22 +201,28 @@ class nova::compute (
|
||||
}
|
||||
}
|
||||
|
||||
if $default_availability_zone {
|
||||
nova_config {
|
||||
'DEFAULT/default_availability_zone':value => $default_availability_zone;
|
||||
}
|
||||
package { 'pm-utils':
|
||||
ensure => present,
|
||||
}
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/force_raw_images': value => $force_raw_images;
|
||||
}
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/default_availability_zone': value => $default_availability_zone;
|
||||
'DEFAULT/internal_service_availability_zone': value => $internal_service_availability_zone;
|
||||
}
|
||||
|
||||
if $default_schedule_zone {
|
||||
nova_config {
|
||||
'DEFAULT/default_schedule_zone':value => $default_schedule_zone;
|
||||
'DEFAULT/default_schedule_zone': value => $default_schedule_zone;
|
||||
}
|
||||
}
|
||||
|
||||
if $internal_service_availability_zone {
|
||||
if ($pci_passthrough) {
|
||||
nova_config {
|
||||
'DEFAULT/internal_service_availability_zone':value => $internal_service_availability_zone;
|
||||
'DEFAULT/pci_passthrough_whitelist': value => check_array_of_hash($pci_passthrough);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
#
|
||||
# This is a temporary manifest that patches
|
||||
# nova compute to resolve the folowing issue:
|
||||
# https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/996840
|
||||
#
|
||||
# This is only intended as a temporary fix and needs to be removed
|
||||
# once the issue is resolved with upstream.
|
||||
#
|
||||
# TODO - check if this is still required for folsom
|
||||
#
|
||||
#
|
||||
class nova::compute::file_hack() {
|
||||
|
||||
# this only works on Ubunty
|
||||
|
||||
File {
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '755',
|
||||
require => Package['nova-compute'],
|
||||
notify => Service['nova-compute'],
|
||||
}
|
||||
|
||||
file { '/usr/lib/python2.7/dist-packages/nova/virt/libvirt/connection.py':
|
||||
source => 'puppet:///modules/nova/connection.py',
|
||||
}
|
||||
|
||||
file { '/usr/lib/python2.7/dist-packages/nova/rootwrap/compute.py':
|
||||
source => 'puppet:///modules/nova/compute.py',
|
||||
}
|
||||
}
|
49
deployment/puppet/nova/manifests/compute/ironic.pp
Normal file
49
deployment/puppet/nova/manifests/compute/ironic.pp
Normal file
@ -0,0 +1,49 @@
|
||||
# == Class: nova::compute::ironic
|
||||
#
|
||||
# Configures Nova compute service to use Ironic.
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# [*admin_user*]
|
||||
# Admin username
|
||||
# The admin username for Ironic to connect to Nova.
|
||||
# Defaults to 'admin'
|
||||
#
|
||||
# [*admin_passwd*]
|
||||
# Admin password
|
||||
# The admin password for Ironic to connect to Nova.
|
||||
# Defaults to 'ironic'
|
||||
#
|
||||
# [*admin_url*]
|
||||
# Admin url
|
||||
# The address of the Keystone api endpoint.
|
||||
# Defaults to 'http://127.0.0.1:35357/v2.0'
|
||||
#
|
||||
# [*admin_tenant_name*]
|
||||
# Admin tenant name
|
||||
# The Ironic Keystone tenant name.
|
||||
# Defaults to 'services'
|
||||
#
|
||||
# [*api_endpoint*]
|
||||
# Api endpoint
|
||||
# The url for Ironic api endpoint.
|
||||
# Defaults to 'http://127.0.0.1:6385/v1'
|
||||
#
|
||||
|
||||
class nova::compute::ironic (
|
||||
$admin_user = 'admin',
|
||||
$admin_passwd = 'ironic',
|
||||
$admin_url = 'http://127.0.0.1:35357/v2.0',
|
||||
$admin_tenant_name = 'services',
|
||||
$api_endpoint = 'http://127.0.0.1:6385/v1',
|
||||
) {
|
||||
|
||||
nova_config {
|
||||
'ironic/admin_username': value => $admin_user;
|
||||
'ironic/admin_password': value => $admin_passwd;
|
||||
'ironic/admin_url': value => $admin_url;
|
||||
'ironic/admin_tenant_name': value => $admin_tenant_name;
|
||||
'ironic/api_endpoint': value => $api_endpoint;
|
||||
'DEFAULT/compute_driver': value => 'nova.virt.ironic.IronicDriver';
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
#
|
||||
# [*libvirt_virt_type*]
|
||||
# (optional) Libvirt domain type. Options are: kvm, lxc, qemu, uml, xen
|
||||
# Replaces libvirt_type
|
||||
# Defaults to 'kvm'
|
||||
#
|
||||
# [*vncserver_listen*]
|
||||
@ -20,9 +19,9 @@
|
||||
#
|
||||
# [*libvirt_cpu_mode*]
|
||||
# (optional) The libvirt CPU mode to configure. Possible values
|
||||
# include custom, host-model, None, host-passthrough.
|
||||
# include custom, host-model, none, host-passthrough.
|
||||
# Defaults to 'host-model' if libvirt_virt_type is set to either
|
||||
# kvm or qemu, otherwise defaults to 'None'.
|
||||
# kvm or qemu, otherwise defaults to 'none'.
|
||||
#
|
||||
# [*libvirt_disk_cachemodes*]
|
||||
# (optional) A list of cachemodes for different disk types, e.g.
|
||||
@ -31,6 +30,20 @@
|
||||
# will be removed from nova.conf completely.
|
||||
# Defaults to an empty list
|
||||
#
|
||||
# [*libvirt_inject_password*]
|
||||
# (optional) Inject the admin password at boot time, without an agent.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*libvirt_inject_key*]
|
||||
# (optional) Inject the ssh public key at boot time.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*libvirt_inject_partition*]
|
||||
# (optional) The partition to inject to : -2 => disable, -1 => inspect
|
||||
# (libguestfs only), 0 => not partitioned, >0 => partition
|
||||
# number (integer value)
|
||||
# Defaults to -2
|
||||
#
|
||||
# [*remove_unused_base_images*]
|
||||
# (optional) Should unused base images be removed?
|
||||
# If undef is specified, remove the line in nova.conf
|
||||
@ -61,40 +74,38 @@
|
||||
# how many seconds it will be removed.
|
||||
# Defaults to undef
|
||||
#
|
||||
|
||||
# [*libvirt_service_name*]
|
||||
# (optional) libvirt service name.
|
||||
# Defaults to $::nova::params::libvirt_service_name
|
||||
#
|
||||
class nova::compute::libvirt (
|
||||
$libvirt_virt_type = 'kvm',
|
||||
$vncserver_listen = '127.0.0.1',
|
||||
$migration_support = false,
|
||||
$libvirt_cpu_mode = false,
|
||||
$libvirt_disk_cachemodes = [],
|
||||
$libvirt_inject_password = false,
|
||||
$libvirt_inject_key = false,
|
||||
$libvirt_inject_partition = -2,
|
||||
$remove_unused_base_images = undef,
|
||||
$remove_unused_kernels = undef,
|
||||
$remove_unused_resized_minimum_age_seconds = undef,
|
||||
$remove_unused_original_minimum_age_seconds = undef,
|
||||
# DEPRECATED PARAMETER
|
||||
$libvirt_type = false
|
||||
) {
|
||||
$libvirt_service_name = $::nova::params::libvirt_service_name,
|
||||
) inherits nova::params {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
Service['libvirt'] -> Service['nova-compute']
|
||||
|
||||
if $libvirt_type {
|
||||
warning ('The libvirt_type parameter is deprecated, use libvirt_virt_type instead.')
|
||||
$libvirt_virt_type_real = $libvirt_type
|
||||
} else {
|
||||
$libvirt_virt_type_real = $libvirt_virt_type
|
||||
}
|
||||
|
||||
# libvirt_cpu_mode has different defaults depending on hypervisor.
|
||||
if !$libvirt_cpu_mode {
|
||||
case $libvirt_virt_type_real {
|
||||
case $libvirt_virt_type {
|
||||
'kvm','qemu': {
|
||||
$libvirt_cpu_mode_real = 'host-model'
|
||||
}
|
||||
default: {
|
||||
$libvirt_cpu_mode_real = 'None'
|
||||
$libvirt_cpu_mode_real = 'none'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -102,10 +113,11 @@ class nova::compute::libvirt (
|
||||
}
|
||||
|
||||
if($::osfamily == 'Debian') {
|
||||
package { "nova-compute-${libvirt_virt_type_real}":
|
||||
package { "nova-compute-${libvirt_virt_type}":
|
||||
ensure => present,
|
||||
before => Package['nova-compute'],
|
||||
require => User['nova'],
|
||||
require => Package['nova-common'],
|
||||
tag => ['openstack'],
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,17 +125,17 @@ class nova::compute::libvirt (
|
||||
service { 'messagebus':
|
||||
ensure => running,
|
||||
enable => true,
|
||||
name => $::nova::params::messagebus_service_name,
|
||||
provider => $::nova::params::special_service_provider,
|
||||
}
|
||||
Package['libvirt'] -> Service['messagebus'] -> Service['libvirt']
|
||||
|
||||
}
|
||||
|
||||
if $migration_support {
|
||||
if $vncserver_listen != '0.0.0.0' {
|
||||
fail('For migration support to work, you MUST set vncserver_listen to \'0.0.0.0\'')
|
||||
if $vncserver_listen != '0.0.0.0' and $vncserver_listen != '::0' {
|
||||
fail('For migration support to work, you MUST set vncserver_listen to \'0.0.0.0\' or \'::0\'')
|
||||
} else {
|
||||
class { 'nova::migration::libvirt': }
|
||||
class { '::nova::migration::libvirt': }
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +147,7 @@ class nova::compute::libvirt (
|
||||
service { 'libvirt' :
|
||||
ensure => running,
|
||||
enable => true,
|
||||
name => $::nova::params::libvirt_service_name,
|
||||
name => $libvirt_service_name,
|
||||
provider => $::nova::params::special_service_provider,
|
||||
require => Package['libvirt'],
|
||||
}
|
||||
@ -143,8 +155,11 @@ class nova::compute::libvirt (
|
||||
nova_config {
|
||||
'DEFAULT/compute_driver': value => 'libvirt.LibvirtDriver';
|
||||
'DEFAULT/vncserver_listen': value => $vncserver_listen;
|
||||
'libvirt/virt_type': value => $libvirt_virt_type_real;
|
||||
'libvirt/virt_type': value => $libvirt_virt_type;
|
||||
'libvirt/cpu_mode': value => $libvirt_cpu_mode_real;
|
||||
'libvirt/inject_password': value => $libvirt_inject_password;
|
||||
'libvirt/inject_key': value => $libvirt_inject_key;
|
||||
'libvirt/inject_partition': value => $libvirt_inject_partition;
|
||||
}
|
||||
|
||||
if size($libvirt_disk_cachemodes) > 0 {
|
||||
|
@ -10,9 +10,14 @@
|
||||
# (optional) The libvirt VIF driver to configure the VIFs.
|
||||
# Defaults to 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver'.
|
||||
#
|
||||
|
||||
# [*force_snat_range*]
|
||||
# (optional) Force SNAT rule to specified network for nova-network
|
||||
# Default to 0.0.0.0/0
|
||||
# Due to architecture constraints in nova_config, it's not possible to setup
|
||||
# more than one SNAT rule though initial parameter is MultiStrOpt
|
||||
class nova::compute::neutron (
|
||||
$libvirt_vif_driver = 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver'
|
||||
$libvirt_vif_driver = 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver',
|
||||
$force_snat_range = '0.0.0.0/0',
|
||||
) {
|
||||
|
||||
if $libvirt_vif_driver == 'nova.virt.libvirt.vif.LibvirtOpenVswitchDriver' {
|
||||
@ -22,4 +27,21 @@ class nova::compute::neutron (
|
||||
nova_config {
|
||||
'libvirt/vif_driver': value => $libvirt_vif_driver;
|
||||
}
|
||||
|
||||
if $libvirt_vif_driver == 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver' and $force_snat_range {
|
||||
# Validate ip and mask for force_snat_range
|
||||
$force_snat_range_array = split($force_snat_range, '/')
|
||||
if is_ip_address($force_snat_range_array[0]) and is_integer($force_snat_range_array[1]) {
|
||||
nova_config {
|
||||
'DEFAULT/force_snat_range': value => $force_snat_range;
|
||||
}
|
||||
} else {
|
||||
fail('force_snat_range should be IPv4 or IPv6 CIDR notation')
|
||||
}
|
||||
} else {
|
||||
nova_config {
|
||||
'DEFAULT/force_snat_range': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,15 +38,28 @@
|
||||
# Required to use cephx.
|
||||
# Default to false.
|
||||
#
|
||||
# [*libvirt_rbd_secret_key*]
|
||||
# (optional) The cephx key to use as key for the libvirt secret,
|
||||
# it must be base64 encoded; when not provided this key will be
|
||||
# requested to the ceph cluster, which assumes the node is
|
||||
# provided of the client.admin keyring as well.
|
||||
# Default to undef.
|
||||
#
|
||||
# [*rbd_keyring*]
|
||||
# (optional) The keyring name to use when retrieving the RBD secret
|
||||
# Default to 'client.nova'
|
||||
#
|
||||
|
||||
class nova::compute::rbd (
|
||||
$libvirt_rbd_user,
|
||||
$libvirt_rbd_secret_uuid = false,
|
||||
$libvirt_rbd_secret_key = undef,
|
||||
$libvirt_images_rbd_pool = 'rbd',
|
||||
$libvirt_images_rbd_ceph_conf = '/etc/ceph/ceph.conf',
|
||||
$rbd_keyring = 'client.nova',
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
nova_config {
|
||||
'libvirt/images_type': value => 'rbd';
|
||||
@ -61,7 +74,8 @@ class nova::compute::rbd (
|
||||
}
|
||||
|
||||
file { '/etc/nova/secret.xml':
|
||||
content => template('nova/secret.xml-compute.erb')
|
||||
content => template('nova/secret.xml-compute.erb'),
|
||||
require => Class['::nova']
|
||||
}
|
||||
|
||||
exec { 'get-or-set virsh secret':
|
||||
@ -70,8 +84,14 @@ class nova::compute::rbd (
|
||||
require => File['/etc/nova/secret.xml']
|
||||
}
|
||||
|
||||
if $libvirt_rbd_secret_key {
|
||||
$libvirt_key = $libvirt_rbd_secret_key
|
||||
} else {
|
||||
$libvirt_key = "$(ceph auth get-key ${rbd_keyring})"
|
||||
}
|
||||
exec { 'set-secret-value virsh':
|
||||
command => '/usr/bin/virsh secret-set-value --secret $(cat /etc/nova/virsh.secret) --base64 $(ceph auth get-key client.nova)',
|
||||
command => "/usr/bin/virsh secret-set-value --secret ${libvirt_rbd_secret_uuid} --base64 ${libvirt_key}",
|
||||
unless => "/usr/bin/virsh secret-get-value ${libvirt_rbd_secret_uuid}",
|
||||
require => Exec['get-or-set virsh secret']
|
||||
}
|
||||
|
||||
|
39
deployment/puppet/nova/manifests/compute/serial.pp
Normal file
39
deployment/puppet/nova/manifests/compute/serial.pp
Normal file
@ -0,0 +1,39 @@
|
||||
# == Class: nova::compute::serial
|
||||
#
|
||||
# Configures nova serial console
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# [*port_range*]
|
||||
# (optional) Range of TCP ports to use for serial ports on compute hosts
|
||||
# Defaults to 10000:20000
|
||||
#
|
||||
# [*base_url*]
|
||||
# (optional) URL that gets passed to the clients
|
||||
# Defaults to 'ws://127.0.0.1:6083/'
|
||||
#
|
||||
# [*listen*]
|
||||
# IP address on which instance serial console should listen
|
||||
# Defaults to 127.0.0.1
|
||||
#
|
||||
# [*proxyclient_address*]
|
||||
# The address to which proxy clients (like nova-serialproxy)
|
||||
# should connect (string value)
|
||||
# Defaults to 127.0.0.1
|
||||
#
|
||||
class nova::compute::serial(
|
||||
$port_range = '10000:20000',
|
||||
$base_url = 'ws://127.0.0.1:6083/',
|
||||
$listen = '127.0.0.1',
|
||||
$proxyclient_address = '127.0.0.1',
|
||||
) {
|
||||
|
||||
|
||||
nova_config {
|
||||
'serial_console/enabled': value => true;
|
||||
'serial_console/port_range': value => $port_range;
|
||||
'serial_console/base_url': value => $base_url;
|
||||
'serial_console/listen': value => $listen;
|
||||
'serial_console/proxyclient_address': value => $proxyclient_address;
|
||||
}
|
||||
}
|
@ -16,13 +16,19 @@
|
||||
# (optional) The state of the nova conductor package
|
||||
# Defaults to 'present'
|
||||
#
|
||||
# [*workers*]
|
||||
# (optional) Number of workers for OpenStack Conductor service
|
||||
# Defaults to undef (i.e. parameter will not be present)
|
||||
#
|
||||
class nova::conductor(
|
||||
$enabled = false,
|
||||
$manage_service = true,
|
||||
$ensure_package = 'present'
|
||||
$ensure_package = 'present',
|
||||
$workers = undef,
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::db
|
||||
include ::nova::params
|
||||
|
||||
nova::generic_service { 'conductor':
|
||||
enabled => $enabled,
|
||||
@ -32,4 +38,9 @@ class nova::conductor(
|
||||
ensure_package => $ensure_package,
|
||||
}
|
||||
|
||||
if $workers {
|
||||
nova_config {
|
||||
'conductor/workers': value => $workers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,13 @@
|
||||
# NOTE: The configuration MUST NOT be already handled by this module
|
||||
# or Puppet catalog compilation will fail with duplicate resources.
|
||||
#
|
||||
# [*nova_paste_api_ini*]
|
||||
# (optional) Allow configuration of arbitrary Nova paste api configurations.
|
||||
# The value is an hash of nova_paste_api_ini resources. Example:
|
||||
# { 'DEFAULT/foo' => { value => 'fooValue'},
|
||||
# 'DEFAULT/bar' => { value => 'barValue'}
|
||||
# }
|
||||
#
|
||||
class nova::config (
|
||||
$nova_config = {},
|
||||
$nova_paste_api_ini = {},
|
||||
|
@ -25,7 +25,7 @@ class nova::consoleauth(
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
nova::generic_service { 'consoleauth':
|
||||
enabled => $enabled,
|
||||
@ -33,7 +33,7 @@ class nova::consoleauth(
|
||||
package_name => $::nova::params::consoleauth_package_name,
|
||||
service_name => $::nova::params::consoleauth_service_name,
|
||||
ensure_package => $ensure_package,
|
||||
require => User['nova'],
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# == Class: nova::cron::archive_deleted_rows
|
||||
#
|
||||
# Move deleted instances to another table that you don't have to backup
|
||||
# unless you have data retention policies.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*minute*]
|
||||
# (optional) Defaults to '1'.
|
||||
#
|
||||
# [*hour*]
|
||||
# (optional) Defaults to '0'.
|
||||
#
|
||||
# [*monthday*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*month*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*weekday*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*max_rows*]
|
||||
# (optional) Maximum number of deleted rows to archive.
|
||||
# Defaults to '100'.
|
||||
#
|
||||
# [*user*]
|
||||
# (optional) User with access to nova files.
|
||||
# Defaults to 'nova'.
|
||||
#
|
||||
class nova::cron::archive_deleted_rows (
|
||||
$minute = 1,
|
||||
$hour = 0,
|
||||
$monthday = '*',
|
||||
$month = '*',
|
||||
$weekday = '*',
|
||||
$max_rows = '100',
|
||||
$user = 'nova',
|
||||
) {
|
||||
|
||||
cron { 'nova-manage db archive_deleted_rows':
|
||||
command => "nova-manage db archive_deleted_rows --max_rows ${max_rows} >>/var/log/nova/nova-rowsflush.log 2>&1",
|
||||
environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
user => $user,
|
||||
minute => $minute,
|
||||
hour => $hour,
|
||||
monthday => $monthday,
|
||||
month => $month,
|
||||
weekday => $weekday,
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
}
|
71
deployment/puppet/nova/manifests/db.pp
Normal file
71
deployment/puppet/nova/manifests/db.pp
Normal file
@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# == Class: nova::db
|
||||
# Configures the nova database.
|
||||
#
|
||||
# == Parameters
|
||||
#
|
||||
# [*database_connection*]
|
||||
# (optional) Connection url to connect to nova database.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*slave_connection*]
|
||||
# (optional) Connection url to connect to nova slave database (read-only).
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*database_idle_timeout*]
|
||||
# (optional) Timeout before idle db connections are reaped.
|
||||
# Defaults to undef
|
||||
#
|
||||
class nova::db (
|
||||
$database_connection = undef,
|
||||
$slave_connection = undef,
|
||||
$database_idle_timeout = undef,
|
||||
) {
|
||||
|
||||
$database_connection_real = pick($database_connection, $::nova::database_connection, false)
|
||||
$slave_connection_real = pick($slave_connection, $::nova::slave_connection, false)
|
||||
$database_idle_timeout_real = pick($database_idle_timeout, $::nova::database_idle_timeout, false)
|
||||
|
||||
if $database_connection_real {
|
||||
if($database_connection_real =~ /mysql:\/\/\S+:\S+@\S+\/\S+/) {
|
||||
require 'mysql::bindings'
|
||||
require 'mysql::bindings::python'
|
||||
} elsif($database_connection_real =~ /postgresql:\/\/\S+:\S+@\S+\/\S+/) {
|
||||
|
||||
} elsif($database_connection_real =~ /sqlite:\/\//) {
|
||||
|
||||
} else {
|
||||
fail("Invalid db connection ${database_connection_real}")
|
||||
}
|
||||
nova_config {
|
||||
'database/connection': value => $database_connection_real, secret => true;
|
||||
'database/idle_timeout': value => $database_idle_timeout_real;
|
||||
}
|
||||
if $slave_connection_real {
|
||||
nova_config {
|
||||
'database/slave_connection': value => $slave_connection_real, secret => true;
|
||||
}
|
||||
} else {
|
||||
nova_config {
|
||||
'database/slave_connection': ensure => absent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -21,11 +21,11 @@
|
||||
#
|
||||
# [*charset*]
|
||||
# (optional) The charset to use for the nova database
|
||||
# Defaults to 'latin1'
|
||||
# Defaults to 'utf8'
|
||||
#
|
||||
# [*collate*]
|
||||
# (optional) The collate to use for the nova database
|
||||
# Defaults to 'latin1_swedish_ci'
|
||||
# Defaults to 'utf8_general_ci'
|
||||
#
|
||||
# [*allowed_hosts*]
|
||||
# (optional) Additional hosts that are allowed to access this DB
|
||||
@ -36,64 +36,32 @@
|
||||
# Defaults to 'localzone'
|
||||
#
|
||||
# [*mysql_module*]
|
||||
# (optional) Mysql puppet module version to use. Tested versions
|
||||
# are 0.9 and 2.2.
|
||||
# Defaults to '0.9'
|
||||
# (optional) Deprecated. Does nothing.
|
||||
#
|
||||
class nova::db::mysql(
|
||||
$password,
|
||||
$dbname = 'nova',
|
||||
$user = 'nova',
|
||||
$host = '127.0.0.1',
|
||||
$charset = 'latin1',
|
||||
$collate = 'latin1_swedish_ci',
|
||||
$charset = 'utf8',
|
||||
$collate = 'utf8_general_ci',
|
||||
$allowed_hosts = undef,
|
||||
$mysql_module = '0.9',
|
||||
$cluster_id = undef
|
||||
$mysql_module = undef,
|
||||
) {
|
||||
|
||||
if $cluster_id {
|
||||
warning('The cluster_id parameter is deprecated and has no effect.')
|
||||
if $mysql_module {
|
||||
warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.')
|
||||
}
|
||||
|
||||
if ($mysql_module >= 2.2) {
|
||||
mysql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
collate => $collate,
|
||||
require => Class['mysql::server'],
|
||||
}
|
||||
} else {
|
||||
require 'mysql::python'
|
||||
|
||||
mysql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
require => Class['mysql::config'],
|
||||
}
|
||||
::openstacklib::db::mysql { 'nova':
|
||||
user => $user,
|
||||
password_hash => mysql_password($password),
|
||||
dbname => $dbname,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
collate => $collate,
|
||||
allowed_hosts => $allowed_hosts,
|
||||
}
|
||||
|
||||
# Create the db instance before openstack-nova if its installed
|
||||
Mysql::Db[$dbname] -> Anchor<| title == 'nova-start' |>
|
||||
Mysql::Db[$dbname] ~> Exec<| title == 'nova-db-sync' |>
|
||||
|
||||
# Check allowed_hosts to avoid duplicate resource declarations
|
||||
if is_array($allowed_hosts) and delete($allowed_hosts,$host) != [] {
|
||||
$real_allowed_hosts = delete($allowed_hosts,$host)
|
||||
} elsif is_string($allowed_hosts) and ($allowed_hosts != $host) {
|
||||
$real_allowed_hosts = $allowed_hosts
|
||||
}
|
||||
|
||||
if $real_allowed_hosts {
|
||||
nova::db::mysql::host_access { $real_allowed_hosts:
|
||||
user => $user,
|
||||
password => $password,
|
||||
database => $dbname,
|
||||
mysql_module => $mysql_module,
|
||||
}
|
||||
}
|
||||
::Openstacklib::Db::Mysql['nova'] ~> Exec<| title == 'nova-db-sync' |>
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
# db/allowed_hosts.pp
|
||||
define nova::db::mysql::host_access ($user, $password, $database, $mysql_module = '0.9') {
|
||||
if ($mysql_module >= 2.2) {
|
||||
mysql_user { "${user}@${name}":
|
||||
password_hash => mysql_password($password),
|
||||
require => Mysql_database[$database],
|
||||
}
|
||||
|
||||
mysql_grant { "${user}@${name}/${database}.*":
|
||||
privileges => ['ALL'],
|
||||
options => ['GRANT'],
|
||||
table => "${database}.*",
|
||||
require => Mysql_user["${user}@${name}"],
|
||||
user => "${user}@${name}"
|
||||
}
|
||||
} else {
|
||||
database_user { "${user}@${name}":
|
||||
password_hash => mysql_password($password),
|
||||
provider => 'mysql',
|
||||
require => Database[$database],
|
||||
}
|
||||
database_grant { "${user}@${name}/${database}":
|
||||
# TODO figure out which privileges to grant.
|
||||
privileges => 'all',
|
||||
provider => 'mysql',
|
||||
require => Database_user["${user}@${name}"]
|
||||
}
|
||||
}
|
||||
}
|
@ -3,34 +3,44 @@
|
||||
# Class that configures postgresql for nova
|
||||
# Requires the Puppetlabs postgresql module.
|
||||
#
|
||||
# === Parameters:
|
||||
# === Parameters
|
||||
#
|
||||
# [*password*]
|
||||
# Password to use to connect to postgresql
|
||||
# (Required) Password to connect to the database.
|
||||
#
|
||||
# [*dbname*]
|
||||
# (optional) Name of the database to create for nova
|
||||
# Defaults to 'nova'
|
||||
# (Optional) Name of the database.
|
||||
# Defaults to 'nova'.
|
||||
#
|
||||
# [*user*]
|
||||
# (optional) Name of the user to connect to postgresql
|
||||
# Defaults to 'nova'
|
||||
# (Optional) User to connect to the database.
|
||||
# Defaults to 'nova'.
|
||||
#
|
||||
# [*encoding*]
|
||||
# (Optional) The charset to use for the database.
|
||||
# Default to undef.
|
||||
#
|
||||
# [*privileges*]
|
||||
# (Optional) Privileges given to the database user.
|
||||
# Default to 'ALL'
|
||||
#
|
||||
class nova::db::postgresql(
|
||||
$password,
|
||||
$dbname = 'nova',
|
||||
$user = 'nova'
|
||||
$dbname = 'nova',
|
||||
$user = 'nova',
|
||||
$encoding = undef,
|
||||
$privileges = 'ALL',
|
||||
) {
|
||||
|
||||
require 'postgresql::python'
|
||||
|
||||
Postgresql::Server::Db[$dbname] -> Anchor<| title == 'nova-start' |>
|
||||
Postgresql::Server::Db[$dbname] ~> Exec<| title == 'nova-db-sync' |>
|
||||
Package['python-psycopg2'] -> Exec<| title == 'nova-db-sync' |>
|
||||
|
||||
postgresql::server::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
::openstacklib::db::postgresql { 'nova':
|
||||
password_hash => postgresql_password($user, $password),
|
||||
dbname => $dbname,
|
||||
user => $user,
|
||||
encoding => $encoding,
|
||||
privileges => $privileges,
|
||||
}
|
||||
|
||||
::Openstacklib::Db::Postgresql['nova'] ~> Exec<| title == 'nova-db-sync' |>
|
||||
::Openstacklib::Db::Postgresql['nova'] -> Anchor<| title == 'nova-start' |>
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ define nova::generic_service(
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
$nova_title = "nova-${name}"
|
||||
# ensure that the service is only started after
|
||||
@ -32,13 +32,22 @@ define nova::generic_service(
|
||||
# I need to mark that ths package should be
|
||||
# installed before nova_config
|
||||
if ($package_name) {
|
||||
if !defined(Package[$package_name]) {
|
||||
if !defined(Package[$nova_title]) and !defined(Package[$package_name]) {
|
||||
package { $nova_title:
|
||||
ensure => $ensure_package,
|
||||
name => $package_name,
|
||||
notify => Service[$nova_title],
|
||||
tag => ['openstack'],
|
||||
}
|
||||
}
|
||||
|
||||
if $service_name {
|
||||
# Do the dependency relationship here in case the package
|
||||
# has been defined elsewhere, either as Package[$nova_title]
|
||||
# or Package[$package_name]
|
||||
Package<| title == $nova_title |> -> Service[$nova_title]
|
||||
Package<| title == $package_name |> -> Service[$nova_title]
|
||||
}
|
||||
}
|
||||
|
||||
if $service_name {
|
||||
@ -54,9 +63,8 @@ define nova::generic_service(
|
||||
ensure => $service_ensure,
|
||||
name => $service_name,
|
||||
enable => $enabled,
|
||||
hasstatus => true,
|
||||
hasrestart => true,
|
||||
require => [Package['nova-common'], Package[$package_name]],
|
||||
hasstatus => true,
|
||||
require => [Package['nova-common']],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,31 +9,24 @@
|
||||
# (optional) The state of nova packages
|
||||
# Defaults to 'present'
|
||||
#
|
||||
# [*nova_cluster_id*]
|
||||
# (optional) Deprecated. This parameter does nothing and will be removed.
|
||||
# Defaults to 'localcluster'
|
||||
#
|
||||
# [*sql_connection*]
|
||||
# (optional) Deprecated. Use database_connection instead.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*sql_idle_timeout*]
|
||||
# (optional) Deprecated. Use database_idle_timeout instead
|
||||
# Defaults to false
|
||||
#
|
||||
# [*database_connection*]
|
||||
# (optional) Connection url to connect to nova database.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*slave_connection*]
|
||||
# (optional) Connection url to connect to nova slave database (read-only).
|
||||
# Defaults to false
|
||||
#
|
||||
# [*database_idle_timeout*]
|
||||
# (optional) Timeout before idle db connections are reaped.
|
||||
# Defaults to 3600
|
||||
#
|
||||
# [*rpc_backend*]
|
||||
# (optional) The rpc backend implementation to use, can be:
|
||||
# nova.openstack.common.rpc.impl_kombu (for rabbitmq)
|
||||
# nova.openstack.common.rpc.impl_qpid (for qpid)
|
||||
# Defaults to 'nova.openstack.common.rpc.impl_kombu'
|
||||
# rabbit (for rabbitmq)
|
||||
# qpid (for qpid)
|
||||
# zmq (for zeromq)
|
||||
# Defaults to 'rabbit'
|
||||
#
|
||||
# [*image_service*]
|
||||
# (optional) Service used to search for and retrieve images.
|
||||
@ -75,6 +68,10 @@
|
||||
# (optional) Connect over SSL for RabbitMQ
|
||||
# Defaults to false
|
||||
#
|
||||
# [*rabbit_ha_queues*]
|
||||
# (optional) Use HA queues in RabbitMQ.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*kombu_ssl_ca_certs*]
|
||||
# (optional) SSL certification authority file (valid only if SSL enabled).
|
||||
# Defaults to undef
|
||||
@ -91,7 +88,7 @@
|
||||
# (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'
|
||||
# Defaults to 'TLSv1'
|
||||
#
|
||||
# [*amqp_durable_queues*]
|
||||
# (optional) Define queues as "durable" to rabbitmq.
|
||||
@ -129,14 +126,14 @@
|
||||
# (optional) Disable Nagle algorithm
|
||||
# Defaults to true
|
||||
#
|
||||
# [*auth_strategy*]
|
||||
# (optional) The strategy to use for auth: noauth or keystone.
|
||||
# Defaults to 'keystone'
|
||||
#
|
||||
# [*service_down_time*]
|
||||
# (optional) Maximum time since last check-in for up service.
|
||||
# Defaults to 60
|
||||
#
|
||||
# [*logdir*]
|
||||
# (optional) Deprecated. Use log_dir instead.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*log_dir*]
|
||||
# (optional) Directory where logs should be stored.
|
||||
# If set to boolean false, it will not log to any directory.
|
||||
@ -155,6 +152,10 @@
|
||||
# (optional) Set log output to verbose output.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*debug*]
|
||||
# (optional) Set log output to debug output.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*periodic_interval*]
|
||||
# (optional) Seconds between running periodic tasks.
|
||||
# Defaults to '60'
|
||||
@ -163,9 +164,9 @@
|
||||
# (optional) Interval at which nodes report to data store.
|
||||
# Defaults to '10'
|
||||
#
|
||||
# [*monitoring_notifications*]
|
||||
# (optional) Whether or not to send system usage data notifications out on the message queue. Only valid for stable/essex.
|
||||
# Defaults to false
|
||||
# [*rootwrap_config*]
|
||||
# (optional) Path to the rootwrap configuration file to use for running commands as root
|
||||
# Defaults to '/etc/nova/rootwrap.conf'
|
||||
#
|
||||
# [*use_syslog*]
|
||||
# (optional) Use syslog for logging
|
||||
@ -175,19 +176,30 @@
|
||||
# (optional) Syslog facility to receive log lines.
|
||||
# Defaults to 'LOG_USER'
|
||||
#
|
||||
# [*nova_user_id*]
|
||||
# (optional) Create the nova user with the specified gid.
|
||||
# Changing to a new uid after specifying a different uid previously,
|
||||
# or using this option after the nova account already exists will break
|
||||
# the ownership of all files/dirs owned by nova.
|
||||
# Defaults to undef.
|
||||
# [*install_utilities*]
|
||||
# (optional) Install nova utilities (Extra packages used by nova tools)
|
||||
# Defaults to true,
|
||||
#
|
||||
# [*nova_group_id*]
|
||||
# (optional) Create the nova user with the specified gid.
|
||||
# Changing to a new uid after specifying a different uid previously,
|
||||
# or using this option after the nova account already exists will break
|
||||
# the ownership of all files/dirs owned by nova.
|
||||
# Defaults to undef.
|
||||
# [*use_ssl*]
|
||||
# (optional) Enable SSL on the API server
|
||||
# Defaults to false, not set
|
||||
#
|
||||
# [*enabled_ssl_apis*]
|
||||
# (optional) List of APIs to SSL enable
|
||||
# Defaults to []
|
||||
# Possible values : 'ec2', 'osapi_compute', 'metadata'
|
||||
#
|
||||
# [*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_
|
||||
#
|
||||
# [*nova_public_key*]
|
||||
# (optional) Install public key in .ssh/authorized_keys for the 'nova' user.
|
||||
@ -201,14 +213,8 @@
|
||||
# 'key-data' }, where 'key-type' is one of (ssh-rsa, ssh-dsa, ssh-ecdsa) and
|
||||
# 'key-data' is the contents of the private key file.
|
||||
#
|
||||
# [*nova_shell*]
|
||||
# (optional) Set shell for 'nova' user to the specified value.
|
||||
# Defaults to '/bin/false'.
|
||||
#
|
||||
# [*mysql_module*]
|
||||
# (optional) Mysql module version to use. Tested versions
|
||||
# are 0.9 and 2.2
|
||||
# Defaults to '0.9'
|
||||
# (optional) Deprecated. Does nothing.
|
||||
#
|
||||
# [*notification_driver*]
|
||||
# (optional) Driver or drivers to handle sending notifications.
|
||||
@ -231,11 +237,20 @@
|
||||
# for notifications on VM and task state changes.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*os_region_name*]
|
||||
# (optional) Sets the os_region_name flag. For environments with
|
||||
# more than one endpoint per service, this is required to make
|
||||
# things such as cinder volume attach work. If you don't set this
|
||||
# and you have multiple endpoints, you will get AmbiguousEndpoint
|
||||
# exceptions in the nova API service.
|
||||
# Defaults to undef
|
||||
#
|
||||
class nova(
|
||||
$ensure_package = 'present',
|
||||
$database_connection = false,
|
||||
$slave_connection = false,
|
||||
$database_idle_timeout = 3600,
|
||||
$rpc_backend = 'nova.openstack.common.rpc.impl_kombu',
|
||||
$rpc_backend = 'rabbit',
|
||||
$image_service = 'nova.image.glance.GlanceImageService',
|
||||
# these glance params should be optional
|
||||
# this should probably just be configured as a glance client
|
||||
@ -248,10 +263,11 @@ class nova(
|
||||
$rabbit_userid = 'guest',
|
||||
$rabbit_virtual_host = '/',
|
||||
$rabbit_use_ssl = false,
|
||||
$rabbit_ha_queues = undef,
|
||||
$kombu_ssl_ca_certs = undef,
|
||||
$kombu_ssl_certfile = undef,
|
||||
$kombu_ssl_keyfile = undef,
|
||||
$kombu_ssl_version = 'SSLv3',
|
||||
$kombu_ssl_version = 'TLSv1',
|
||||
$amqp_durable_queues = false,
|
||||
$qpid_hostname = 'localhost',
|
||||
$qpid_port = '5672',
|
||||
@ -271,80 +287,88 @@ class nova(
|
||||
$periodic_interval = '60',
|
||||
$report_interval = '10',
|
||||
$rootwrap_config = '/etc/nova/rootwrap.conf',
|
||||
$nova_user_id = undef,
|
||||
$nova_group_id = undef,
|
||||
$use_ssl = false,
|
||||
$enabled_ssl_apis = ['ec2', 'metadata', 'osapi_compute'],
|
||||
$ca_file = false,
|
||||
$cert_file = false,
|
||||
$key_file = false,
|
||||
$nova_public_key = undef,
|
||||
$nova_private_key = undef,
|
||||
$nova_shell = '/bin/false',
|
||||
# deprecated in folsom
|
||||
#$root_helper = $::nova::params::root_helper,
|
||||
$monitoring_notifications = false,
|
||||
$use_syslog = false,
|
||||
$log_facility = 'LOG_USER',
|
||||
$install_utilities = true,
|
||||
$mysql_module = '0.9',
|
||||
$notification_driver = [],
|
||||
$notification_topics = 'notifications',
|
||||
$notify_api_faults = false,
|
||||
$notify_on_state_change = undef,
|
||||
# DEPRECATED PARAMETERS
|
||||
# this is how to query all resources from our clutser
|
||||
$nova_cluster_id = undef,
|
||||
$sql_connection = false,
|
||||
$sql_idle_timeout = false,
|
||||
$logdir = false,
|
||||
$mysql_module = undef,
|
||||
$os_region_name = undef,
|
||||
) inherits nova::params {
|
||||
|
||||
if $nova_cluster_id {
|
||||
warning('The nova_cluster_id parameter is deprecated and has no effect.')
|
||||
# maintain backward compatibility
|
||||
include ::nova::db
|
||||
|
||||
if $mysql_module {
|
||||
warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.')
|
||||
}
|
||||
|
||||
group { 'nova':
|
||||
ensure => present,
|
||||
system => true,
|
||||
gid => $nova_group_id,
|
||||
before => User['nova'],
|
||||
validate_array($enabled_ssl_apis)
|
||||
if empty($enabled_ssl_apis) and $use_ssl {
|
||||
warning('enabled_ssl_apis is empty but use_ssl is set to true')
|
||||
}
|
||||
|
||||
user { 'nova':
|
||||
ensure => present,
|
||||
system => true,
|
||||
groups => 'nova',
|
||||
home => '/var/lib/nova',
|
||||
managehome => false,
|
||||
shell => $nova_shell,
|
||||
uid => $nova_user_id,
|
||||
gid => $nova_group_id,
|
||||
if $use_ssl {
|
||||
if !$cert_file {
|
||||
fail('The cert_file parameter is required when use_ssl is set to true')
|
||||
}
|
||||
if !$key_file {
|
||||
fail('The key_file parameter is required when use_ssl is set to true')
|
||||
}
|
||||
}
|
||||
|
||||
if $kombu_ssl_ca_certs and !$rabbit_use_ssl {
|
||||
fail('The kombu_ssl_ca_certs parameter requires rabbit_use_ssl to be set to true')
|
||||
}
|
||||
if $kombu_ssl_certfile and !$rabbit_use_ssl {
|
||||
fail('The kombu_ssl_certfile parameter requires rabbit_use_ssl to be set to true')
|
||||
}
|
||||
if $kombu_ssl_keyfile and !$rabbit_use_ssl {
|
||||
fail('The kombu_ssl_keyfile parameter requires rabbit_use_ssl to be set to true')
|
||||
}
|
||||
if ($kombu_ssl_certfile and !$kombu_ssl_keyfile) or ($kombu_ssl_keyfile and !$kombu_ssl_certfile) {
|
||||
fail('The kombu_ssl_certfile and kombu_ssl_keyfile parameters must be used together')
|
||||
}
|
||||
|
||||
if $nova_public_key or $nova_private_key {
|
||||
file { '/var/lib/nova/.ssh':
|
||||
ensure => directory,
|
||||
mode => '0700',
|
||||
owner => nova,
|
||||
group => nova,
|
||||
ensure => directory,
|
||||
mode => '0700',
|
||||
owner => 'nova',
|
||||
group => 'nova',
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
|
||||
if $nova_public_key {
|
||||
if ! $nova_public_key[key] or ! $nova_public_key[type] {
|
||||
if ! $nova_public_key['key'] or ! $nova_public_key['type'] {
|
||||
fail('You must provide both a key type and key data.')
|
||||
}
|
||||
|
||||
ssh_authorized_key { 'nova-migration-public-key':
|
||||
ensure => present,
|
||||
key => $nova_public_key[key],
|
||||
type => $nova_public_key[type],
|
||||
key => $nova_public_key['key'],
|
||||
type => $nova_public_key['type'],
|
||||
user => 'nova',
|
||||
require => File['/var/lib/nova/.ssh'],
|
||||
}
|
||||
}
|
||||
|
||||
if $nova_private_key {
|
||||
if ! $nova_private_key[key] or ! $nova_private_key[type] {
|
||||
if ! $nova_private_key[key] or ! $nova_private_key['type'] {
|
||||
fail('You must provide both a key type and key data.')
|
||||
}
|
||||
|
||||
$nova_private_key_file = $nova_private_key[type] ? {
|
||||
$nova_private_key_file = $nova_private_key['type'] ? {
|
||||
'ssh-rsa' => '/var/lib/nova/.ssh/id_rsa',
|
||||
'ssh-dsa' => '/var/lib/nova/.ssh/id_dsa',
|
||||
'ssh-ecdsa' => '/var/lib/nova/.ssh/id_ecdsa',
|
||||
@ -352,15 +376,15 @@ class nova(
|
||||
}
|
||||
|
||||
if ! $nova_private_key_file {
|
||||
fail("Unable to determine name of private key file. Type specified was '${nova_private_key[type]}' but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.")
|
||||
fail("Unable to determine name of private key file. Type specified was '${nova_private_key['type']}' but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.")
|
||||
}
|
||||
|
||||
file { $nova_private_key_file:
|
||||
content => $nova_private_key[key],
|
||||
mode => '0600',
|
||||
owner => nova,
|
||||
group => nova,
|
||||
require => File['/var/lib/nova/.ssh'],
|
||||
owner => 'nova',
|
||||
group => 'nova',
|
||||
require => [ File['/var/lib/nova/.ssh'], Package['nova-common'] ],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,24 +397,14 @@ class nova(
|
||||
Package['nova-common'] -> Nova_config<| |> -> File['/etc/nova/nova.conf']
|
||||
Nova_config<| |> ~> Exec['post-nova_config']
|
||||
|
||||
File {
|
||||
require => Package['nova-common'],
|
||||
owner => 'nova',
|
||||
group => 'nova',
|
||||
}
|
||||
|
||||
# TODO - see if these packages can be removed
|
||||
# they should be handled as package deps by the OS
|
||||
package { 'python':
|
||||
ensure => present,
|
||||
}
|
||||
package { 'python-greenlet':
|
||||
ensure => present,
|
||||
require => Package['python'],
|
||||
}
|
||||
|
||||
if $install_utilities {
|
||||
class { 'nova::utilities': }
|
||||
class { '::nova::utilities': }
|
||||
}
|
||||
|
||||
# this anchor is used to simplify the graph between nova components by
|
||||
@ -399,17 +413,22 @@ class nova(
|
||||
|
||||
package { 'python-nova':
|
||||
ensure => $ensure_package,
|
||||
require => Package['python-greenlet']
|
||||
require => Package['python-greenlet'],
|
||||
tag => ['openstack'],
|
||||
}
|
||||
|
||||
package { 'nova-common':
|
||||
ensure => $ensure_package,
|
||||
name => $::nova::params::common_package_name,
|
||||
require => [Package['python-nova'], Anchor['nova-start'], User['nova']]
|
||||
require => [Package['python-nova'], Anchor['nova-start']],
|
||||
tag => ['openstack'],
|
||||
}
|
||||
|
||||
file { '/etc/nova/nova.conf':
|
||||
mode => '0640',
|
||||
mode => '0640',
|
||||
owner => 'nova',
|
||||
group => 'nova',
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
|
||||
# used by debian/ubuntu in nova::network_bridge to refresh
|
||||
@ -419,48 +438,11 @@ class nova(
|
||||
refreshonly => true,
|
||||
}
|
||||
|
||||
if $sql_connection {
|
||||
warning('The sql_connection parameter is deprecated, use database_connection instead.')
|
||||
$database_connection_real = $sql_connection
|
||||
} else {
|
||||
$database_connection_real = $database_connection
|
||||
}
|
||||
|
||||
if $sql_idle_timeout {
|
||||
warning('The sql_idle_timeout parameter is deprecated, use database_idle_timeout instead.')
|
||||
$database_idle_timeout_real = $sql_idle_timeout
|
||||
} else {
|
||||
$database_idle_timeout_real = $database_idle_timeout
|
||||
}
|
||||
|
||||
# both the database_connection and rabbit_host are things
|
||||
# that may need to be collected from a remote host
|
||||
if $database_connection_real {
|
||||
if($database_connection_real =~ /mysql:\/\/\S+:\S+@\S+\/\S+/) {
|
||||
if ($mysql_module >= 2.2) {
|
||||
require 'mysql::bindings'
|
||||
require 'mysql::bindings::python'
|
||||
} else {
|
||||
require 'mysql::python'
|
||||
}
|
||||
} elsif($database_connection_real =~ /postgresql:\/\/\S+:\S+@\S+\/\S+/) {
|
||||
|
||||
} elsif($database_connection_real =~ /sqlite:\/\//) {
|
||||
|
||||
} else {
|
||||
fail("Invalid db connection ${database_connection_real}")
|
||||
}
|
||||
nova_config {
|
||||
'database/connection': value => $database_connection_real, secret => true;
|
||||
'database/idle_timeout': value => $database_idle_timeout_real;
|
||||
}
|
||||
}
|
||||
|
||||
nova_config { 'DEFAULT/image_service': value => $image_service }
|
||||
|
||||
if $image_service == 'nova.image.glance.GlanceImageService' {
|
||||
if $glance_api_servers {
|
||||
nova_config { 'DEFAULT/glance_api_servers': value => $glance_api_servers }
|
||||
nova_config { 'glance/api_servers': value => $glance_api_servers }
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,61 +454,74 @@ class nova(
|
||||
nova_config { 'DEFAULT/memcached_servers': ensure => absent }
|
||||
}
|
||||
|
||||
if $rpc_backend == 'nova.openstack.common.rpc.impl_kombu' {
|
||||
# we keep "nova.openstack.common.rpc.impl_kombu" for backward compatibility
|
||||
# but since Icehouse, "rabbit" is enough.
|
||||
if $rpc_backend == 'nova.openstack.common.rpc.impl_kombu' or $rpc_backend == 'rabbit' {
|
||||
# I may want to support exporting and collecting these
|
||||
nova_config {
|
||||
'DEFAULT/rabbit_password': value => $rabbit_password, secret => true;
|
||||
'DEFAULT/rabbit_userid': value => $rabbit_userid;
|
||||
'DEFAULT/rabbit_virtual_host': value => $rabbit_virtual_host;
|
||||
'DEFAULT/rabbit_use_ssl': value => $rabbit_use_ssl;
|
||||
'oslo_messaging_rabbit/rabbit_password': value => $rabbit_password, secret => true;
|
||||
'oslo_messaging_rabbit/rabbit_userid': value => $rabbit_userid;
|
||||
'oslo_messaging_rabbit/rabbit_virtual_host': value => $rabbit_virtual_host;
|
||||
'oslo_messaging_rabbit/rabbit_use_ssl': value => $rabbit_use_ssl;
|
||||
'DEFAULT/amqp_durable_queues': value => $amqp_durable_queues;
|
||||
}
|
||||
|
||||
if $rabbit_use_ssl {
|
||||
|
||||
if $kombu_ssl_ca_certs {
|
||||
nova_config { 'DEFAULT/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs }
|
||||
nova_config { 'oslo_messaging_rabbit/kombu_ssl_ca_certs': value => $kombu_ssl_ca_certs; }
|
||||
} else {
|
||||
nova_config { 'DEFAULT/kombu_ssl_ca_certs': ensure => absent}
|
||||
nova_config { 'oslo_messaging_rabbit/kombu_ssl_ca_certs': ensure => absent; }
|
||||
}
|
||||
|
||||
if $kombu_ssl_certfile {
|
||||
nova_config { 'DEFAULT/kombu_ssl_certfile': value => $kombu_ssl_certfile }
|
||||
if $kombu_ssl_certfile or $kombu_ssl_keyfile {
|
||||
nova_config {
|
||||
'oslo_messaging_rabbit/kombu_ssl_certfile': value => $kombu_ssl_certfile;
|
||||
'oslo_messaging_rabbit/kombu_ssl_keyfile': value => $kombu_ssl_keyfile;
|
||||
}
|
||||
} else {
|
||||
nova_config { 'DEFAULT/kombu_ssl_certfile': ensure => absent}
|
||||
}
|
||||
|
||||
if $kombu_ssl_keyfile {
|
||||
nova_config { 'DEFAULT/kombu_ssl_keyfile': value => $kombu_ssl_keyfile }
|
||||
} else {
|
||||
nova_config { 'DEFAULT/kombu_ssl_keyfile': ensure => absent}
|
||||
nova_config {
|
||||
'oslo_messaging_rabbit/kombu_ssl_certfile': ensure => absent;
|
||||
'oslo_messaging_rabbit/kombu_ssl_keyfile': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $kombu_ssl_version {
|
||||
nova_config { 'DEFAULT/kombu_ssl_version': value => $kombu_ssl_version }
|
||||
nova_config { 'oslo_messaging_rabbit/kombu_ssl_version': value => $kombu_ssl_version; }
|
||||
} else {
|
||||
nova_config { 'DEFAULT/kombu_ssl_version': ensure => absent}
|
||||
nova_config { 'oslo_messaging_rabbit/kombu_ssl_version': ensure => absent; }
|
||||
}
|
||||
|
||||
} else {
|
||||
nova_config {
|
||||
'DEFAULT/kombu_ssl_ca_certs': ensure => absent;
|
||||
'DEFAULT/kombu_ssl_certfile': ensure => absent;
|
||||
'DEFAULT/kombu_ssl_keyfile': ensure => absent;
|
||||
'DEFAULT/kombu_ssl_version': ensure => absent;
|
||||
'oslo_messaging_rabbit/kombu_ssl_ca_certs': ensure => absent;
|
||||
'oslo_messaging_rabbit/kombu_ssl_certfile': ensure => absent;
|
||||
'oslo_messaging_rabbit/kombu_ssl_keyfile': ensure => absent;
|
||||
'oslo_messaging_rabbit/kombu_ssl_version': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $rabbit_hosts {
|
||||
nova_config { 'DEFAULT/rabbit_hosts': value => join($rabbit_hosts, ',') }
|
||||
nova_config { 'DEFAULT/rabbit_ha_queues': value => true }
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_hosts': value => join($rabbit_hosts, ',') }
|
||||
} else {
|
||||
nova_config { 'DEFAULT/rabbit_host': value => $rabbit_host }
|
||||
nova_config { 'DEFAULT/rabbit_port': value => $rabbit_port }
|
||||
nova_config { 'DEFAULT/rabbit_hosts': value => "${rabbit_host}:${rabbit_port}" }
|
||||
nova_config { 'DEFAULT/rabbit_ha_queues': value => false }
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_host': value => $rabbit_host }
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_port': value => $rabbit_port }
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_hosts': value => "${rabbit_host}:${rabbit_port}" }
|
||||
}
|
||||
if $rabbit_ha_queues == undef {
|
||||
if $rabbit_hosts {
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => true }
|
||||
} else {
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => false }
|
||||
}
|
||||
} else {
|
||||
nova_config { 'oslo_messaging_rabbit/rabbit_ha_queues': value => $rabbit_ha_queues }
|
||||
}
|
||||
}
|
||||
|
||||
if $rpc_backend == 'nova.openstack.common.rpc.impl_qpid' {
|
||||
# we keep "nova.openstack.common.rpc.impl_qpid" for backward compatibility
|
||||
# but since Icehouse, "qpid" is enough.
|
||||
if $rpc_backend == 'nova.openstack.common.rpc.impl_qpid' or $rpc_backend == 'qpid' {
|
||||
nova_config {
|
||||
'DEFAULT/qpid_hostname': value => $qpid_hostname;
|
||||
'DEFAULT/qpid_port': value => $qpid_port;
|
||||
@ -553,31 +548,47 @@ class nova(
|
||||
}
|
||||
}
|
||||
|
||||
if $logdir {
|
||||
warning('The logdir parameter is deprecated, use log_dir instead.')
|
||||
$log_dir_real = $logdir
|
||||
# SSL Options
|
||||
if $use_ssl {
|
||||
nova_config {
|
||||
'DEFAULT/enabled_ssl_apis' : value => join($enabled_ssl_apis, ',');
|
||||
'DEFAULT/ssl_cert_file' : value => $cert_file;
|
||||
'DEFAULT/ssl_key_file' : value => $key_file;
|
||||
}
|
||||
if $ca_file {
|
||||
nova_config { 'DEFAULT/ssl_ca_file' :
|
||||
value => $ca_file,
|
||||
}
|
||||
} else {
|
||||
nova_config { 'DEFAULT/ssl_ca_file' :
|
||||
ensure => absent,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$log_dir_real = $log_dir
|
||||
nova_config {
|
||||
'DEFAULT/enabled_ssl_apis' : ensure => absent;
|
||||
'DEFAULT/ssl_cert_file' : ensure => absent;
|
||||
'DEFAULT/ssl_key_file' : ensure => absent;
|
||||
'DEFAULT/ssl_ca_file' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $log_dir_real {
|
||||
file { $log_dir_real:
|
||||
if $log_dir {
|
||||
file { $log_dir:
|
||||
ensure => directory,
|
||||
mode => '0750',
|
||||
owner => 'nova',
|
||||
group => $::nova::params::nova_log_group,
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
nova_config { 'DEFAULT/log_dir': value => $log_dir_real;}
|
||||
nova_config { 'DEFAULT/log_dir': value => $log_dir;}
|
||||
} else {
|
||||
nova_config { 'DEFAULT/log_dir': ensure => absent;}
|
||||
}
|
||||
|
||||
if $monitoring_notifications {
|
||||
warning('The monitoring_notifications parameter is deprecated, use notification_driver instead.')
|
||||
$notification_driver_real = 'nova.openstack.common.notifier.rpc_notifier'
|
||||
} else {
|
||||
$notification_driver_real = is_string($notification_driver) ? {
|
||||
true => $notification_driver,
|
||||
default => join($notification_driver, ',')
|
||||
}
|
||||
$notification_driver_real = is_string($notification_driver) ? {
|
||||
true => $notification_driver,
|
||||
default => join($notification_driver, ',')
|
||||
}
|
||||
|
||||
nova_config {
|
||||
@ -615,6 +626,17 @@ class nova(
|
||||
}
|
||||
}
|
||||
|
||||
if $os_region_name {
|
||||
nova_config {
|
||||
'DEFAULT/os_region_name': value => $os_region_name;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/os_region_name': ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
exec { 'post-nova_config':
|
||||
command => '/bin/echo "Nova config has changed"',
|
||||
refreshonly => true,
|
||||
|
@ -11,29 +11,55 @@
|
||||
# (optional) The name of the nova service user
|
||||
# Defaults to 'nova'
|
||||
#
|
||||
# [*public_address*]
|
||||
# (optional) The public nova-api endpoint
|
||||
# Defaults to '127.0.0.1'
|
||||
# [*auth_name_v3*]
|
||||
# (optional) The name of the nova v3 service user
|
||||
# Defaults to 'novav3'
|
||||
#
|
||||
# [*admin_address*]
|
||||
# (optional) The admin nova-api endpoint
|
||||
# Defaults to '127.0.0.1'
|
||||
# [*service_name*]
|
||||
# (optional) Name of the service.
|
||||
# Defaults to the value of auth_name, but must differ from the value
|
||||
# of service_name_v3.
|
||||
#
|
||||
# [*internal_address*]
|
||||
# (optional) The internal nova-api endpoint
|
||||
# Defaults to '127.0.0.1'
|
||||
# [*service_name_v3*]
|
||||
# (optional) Name of the v3 service.
|
||||
# Defaults to the value of auth_name_v3, but must differ from the value
|
||||
# of service_name.
|
||||
#
|
||||
# [*compute_port*]
|
||||
# (optional) The port to use for the compute endpoint
|
||||
# Defaults to '8774'
|
||||
# [*public_url*]
|
||||
# (optional) The endpoint's public url. (Defaults to 'http://127.0.0.1:8774/v2/%(tenant_id)s')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*ec2_port*]
|
||||
# (optional) The port to use for the ec2 endpoint
|
||||
# Defaults to '8773'
|
||||
# [*internal_url*]
|
||||
# (optional) The endpoint's internal url. (Defaults to 'http://127.0.0.1:8774/v2/%(tenant_id)s')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*compute_version*]
|
||||
# (optional) The version of the compute api to put in the endpoint
|
||||
# Defaults to 'v2'
|
||||
# [*admin_url*]
|
||||
# (optional) The endpoint's admin url. (Defaults to 'http://127.0.0.1:8774/v2/%(tenant_id)s')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*public_url_v3*]
|
||||
# (optional) The v3 endpoint's public url. (Defaults to 'http://127.0.0.1:8774/v3')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*internal_url_v3*]
|
||||
# (optional) The v3 endpoint's internal url. (Defaults to 'http://127.0.0.1:8774/v3')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*admin_url_v3*]
|
||||
# (optional) The v3 endpoint's admin url. (Defaults to 'http://127.0.0.1:8774/v3')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*ec2_public_url*]
|
||||
# (optional) The endpoint's public url for EC2.
|
||||
# (Defaults to 'http://127.0.0.1:8773/services/Cloud')
|
||||
#
|
||||
# [*ec2_internal_url*]
|
||||
# (optional) The endpoint's internal url for EC2.
|
||||
# (Defaults to 'http://127.0.0.1:8773/services/Cloud')
|
||||
#
|
||||
# [*ec2_admin_url*]
|
||||
# (optional) The endpoint's admin url for EC2.
|
||||
# (Defaults to 'http://127.0.0.1:8773/services/Admin')
|
||||
#
|
||||
# [*region*]
|
||||
# (optional) The region in which to place the endpoints
|
||||
@ -55,82 +81,275 @@
|
||||
# (optional) Whether to create the endpoint.
|
||||
# Defaults to true
|
||||
#
|
||||
# [*cinder*]
|
||||
# (optional) Deprecated and has no effect
|
||||
# Defaults to undef
|
||||
# [*configure_endpoint_v3*]
|
||||
# (optional) Whether to create the v3 endpoint.
|
||||
# Defaults to true
|
||||
#
|
||||
# [*configure_user*]
|
||||
# (optional) Whether to create the service user.
|
||||
# Defaults to true
|
||||
#
|
||||
# [*configure_user_role*]
|
||||
# (optional) Whether to configure the admin role for the service user.
|
||||
# Defaults to true
|
||||
#
|
||||
# [*compute_version*]
|
||||
# (optional) DEPRECATED: Use public_url, internal_url and admin_url OR
|
||||
# public_url_v3, internal_url_v3 and admin_url_v3 instead.
|
||||
# The version of the compute api to put in the endpoint. (Defaults to v2)
|
||||
# Setting this parameter overrides public_url, internal_url and admin_url parameters.
|
||||
#
|
||||
# [*compute_port*]
|
||||
# (optional) DEPRECATED: Use public_url, internal_url and admin_url instead.
|
||||
# Port for endpoint. (Defaults to 9696)
|
||||
# Setting this parameter overrides public_url, internal_url and admin_url parameters.
|
||||
#
|
||||
# [*ec2_port*]
|
||||
# (optional) DEPRECATED: Use ec2_public_url, ec2_internal_url and ec2_admin_url instead.
|
||||
# (optional) The port to use for the ec2 endpoint. (Defaults to 8773)
|
||||
#
|
||||
# [*public_protocol*]
|
||||
# (optional) Protocol to use for the public endpoint. Can be http or https.
|
||||
# Defaults to 'http'
|
||||
# (optional) DEPRECATED: Use public_url and ec2_public_url instead.
|
||||
# Protocol for public endpoint. (Defaults to 'http')
|
||||
# Setting this parameter overrides public_url and ec2_public_url parameters.
|
||||
#
|
||||
# [*admin_protocol*]
|
||||
# Protocol for admin endpoints. Defaults to 'http'.
|
||||
# [*public_address*]
|
||||
# (optional) DEPRECATED: Use public_url and ec2_public_url instead.
|
||||
# Public address for endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides public_url and ec2_public_url parameters.
|
||||
#
|
||||
# [*internal_protocol*]
|
||||
# Protocol for internal endpoints. Defaults to 'http'.
|
||||
# (optional) DEPRECATED: Use internal_url and ec2_internal_url instead.
|
||||
# Protocol for internal endpoint. (Defaults to 'http')
|
||||
# Setting this parameter overrides internal_url and ec2_internal_url parameters.
|
||||
#
|
||||
# [*internal_address*]
|
||||
# (optional) DEPRECATED: Use internal_url and ec2_internal_url instead.
|
||||
# Internal address for endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides internal_url and ec2_internal_url parameters.
|
||||
#
|
||||
# [*admin_protocol*]
|
||||
# (optional) DEPRECATED: Use admin_url and ec2_admin_url instead.
|
||||
# Protocol for admin endpoint. (Defaults to 'http')
|
||||
# Setting this parameter overrides admin_url and ec2_admin_url parameters.
|
||||
#
|
||||
# [*admin_address*]
|
||||
# (optional) DEPRECATED: Use admin_url and ec2_admin_url instead.
|
||||
# Admin address for endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides admin_url and ec2_admin_url parameters.
|
||||
#
|
||||
class nova::keystone::auth(
|
||||
$password,
|
||||
$auth_name = 'nova',
|
||||
$public_address = '127.0.0.1',
|
||||
$admin_address = '127.0.0.1',
|
||||
$internal_address = '127.0.0.1',
|
||||
$compute_port = '8774',
|
||||
$ec2_port = '8773',
|
||||
$compute_version = 'v2',
|
||||
$auth_name_v3 = 'novav3',
|
||||
$service_name = undef,
|
||||
$service_name_v3 = undef,
|
||||
$region = 'RegionOne',
|
||||
$tenant = 'services',
|
||||
$email = 'nova@localhost',
|
||||
$public_url = 'http://127.0.0.1:8774/v2/%(tenant_id)s',
|
||||
$internal_url = 'http://127.0.0.1:8774/v2/%(tenant_id)s',
|
||||
$admin_url = 'http://127.0.0.1:8774/v2/%(tenant_id)s',
|
||||
$public_url_v3 = 'http://127.0.0.1:8774/v3',
|
||||
$internal_url_v3 = 'http://127.0.0.1:8774/v3',
|
||||
$admin_url_v3 = 'http://127.0.0.1:8774/v3',
|
||||
$ec2_public_url = 'http://127.0.0.1:8773/services/Cloud',
|
||||
$ec2_internal_url = 'http://127.0.0.1:8773/services/Cloud',
|
||||
$ec2_admin_url = 'http://127.0.0.1:8773/services/Admin',
|
||||
$configure_ec2_endpoint = true,
|
||||
$cinder = undef,
|
||||
$public_protocol = 'http',
|
||||
$configure_endpoint = true,
|
||||
$admin_protocol = 'http',
|
||||
$internal_protocol = 'http'
|
||||
$configure_endpoint_v3 = true,
|
||||
$configure_user = true,
|
||||
$configure_user_role = true,
|
||||
# DEPRECATED PARAMETERS
|
||||
$compute_version = undef,
|
||||
$compute_port = undef,
|
||||
$ec2_port = undef,
|
||||
$public_protocol = undef,
|
||||
$public_address = undef,
|
||||
$admin_protocol = undef,
|
||||
$admin_address = undef,
|
||||
$internal_protocol = undef,
|
||||
$internal_address = undef,
|
||||
) {
|
||||
|
||||
if $cinder != undef {
|
||||
warning('The cinder parameter is deprecated and has no effect.')
|
||||
if $compute_version {
|
||||
warning('The compute_version parameter is deprecated, use public_url, internal_url and admin_url instead.')
|
||||
}
|
||||
|
||||
Keystone_endpoint["${region}/${auth_name}"] ~> Service <| name == 'nova-api' |>
|
||||
if $compute_port {
|
||||
warning('The compute_port parameter is deprecated, use public_url, internal_url and admin_url instead.')
|
||||
}
|
||||
|
||||
keystone_user { $auth_name:
|
||||
ensure => present,
|
||||
password => $password,
|
||||
email => $email,
|
||||
tenant => $tenant,
|
||||
if $ec2_port {
|
||||
warning('The ec2_port parameter is deprecated, use ec2_public_url, ec2_internal_url and ec2_admin_url instead.')
|
||||
}
|
||||
keystone_user_role { "${auth_name}@${tenant}":
|
||||
ensure => present,
|
||||
roles => 'admin',
|
||||
|
||||
if $public_protocol {
|
||||
warning('The public_protocol parameter is deprecated, use public_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The public_protocol parameter is deprecated, use ec2_public_url instead.')
|
||||
}
|
||||
}
|
||||
keystone_service { $auth_name:
|
||||
ensure => present,
|
||||
type => 'compute',
|
||||
description => 'Openstack Compute Service',
|
||||
|
||||
if $internal_protocol {
|
||||
warning('The internal_protocol parameter is deprecated, use internal_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The internal_protocol parameter is deprecated, use ec2_public_url instead.')
|
||||
}
|
||||
}
|
||||
|
||||
if $admin_protocol {
|
||||
warning('The admin_protocol parameter is deprecated, use admin_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The admin_protocol parameter is deprecated, use ec2_admin_url instead.')
|
||||
}
|
||||
}
|
||||
|
||||
if $public_address {
|
||||
warning('The public_address parameter is deprecated, use public_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The public_address parameter is deprecated, use ec2_public_url instead.')
|
||||
}
|
||||
}
|
||||
|
||||
if $internal_address {
|
||||
warning('The internal_address parameter is deprecated, use internal_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The internal_address parameter is deprecated, use ec2_internal_url instead.')
|
||||
}
|
||||
}
|
||||
|
||||
if $admin_address {
|
||||
warning('The admin_address parameter is deprecated, use admin_url instead.')
|
||||
if $configure_ec2_endpoint {
|
||||
warning('The admin_address parameter is deprecated, use ec2_admin_url instead.')
|
||||
}
|
||||
}
|
||||
|
||||
if $service_name == undef {
|
||||
$real_service_name = $auth_name
|
||||
} else {
|
||||
$real_service_name = $service_name
|
||||
}
|
||||
|
||||
if $service_name_v3 == undef {
|
||||
$real_service_name_v3 = $auth_name_v3
|
||||
} else {
|
||||
$real_service_name_v3 = $service_name_v3
|
||||
}
|
||||
|
||||
if $real_service_name == $real_service_name_v3 {
|
||||
fail('nova::keystone::auth parameters service_name and service_name_v3 must be different.')
|
||||
}
|
||||
|
||||
if ($public_protocol or $public_address or $compute_port) {
|
||||
$public_url_real = sprintf('%s://%s:%s/%s/%%(tenant_id)s',
|
||||
pick($public_protocol, 'http'),
|
||||
pick($public_address, '127.0.0.1'),
|
||||
pick($compute_port, '8774'),
|
||||
pick($compute_version, 'v2'))
|
||||
} else {
|
||||
$public_url_real = $public_url
|
||||
}
|
||||
|
||||
if ($internal_protocol or $internal_address or $compute_port) {
|
||||
$internal_url_real = sprintf('%s://%s:%s/%s/%%(tenant_id)s',
|
||||
pick($internal_protocol, 'http'),
|
||||
pick($internal_address, '127.0.0.1'),
|
||||
pick($compute_port, '8774'),
|
||||
pick($compute_version, 'v2'))
|
||||
} else {
|
||||
$internal_url_real = $internal_url
|
||||
}
|
||||
|
||||
if ($admin_protocol or $admin_address or $compute_port) {
|
||||
$admin_url_real = sprintf('%s://%s:%s/%s/%%(tenant_id)s',
|
||||
pick($admin_protocol, 'http'),
|
||||
pick($admin_address, '127.0.0.1'),
|
||||
pick($compute_port, '8774'),
|
||||
pick($compute_version, 'v2'))
|
||||
} else {
|
||||
$admin_url_real = $admin_url
|
||||
}
|
||||
|
||||
# EC2 endpoints
|
||||
if ($public_protocol or $public_address or $ec2_port) {
|
||||
$ec2_public_url_real = sprintf('%s://%s:%s/services/Cloud',
|
||||
pick($public_protocol, 'http'),
|
||||
pick($public_address, '127.0.0.1'),
|
||||
pick($ec2_port, '8773'))
|
||||
} else {
|
||||
$ec2_public_url_real = $ec2_public_url
|
||||
}
|
||||
|
||||
if ($internal_protocol or $internal_address or $ec2_port) {
|
||||
$ec2_internal_url_real = sprintf('%s://%s:%s/services/Cloud',
|
||||
pick($internal_protocol, 'http'),
|
||||
pick($internal_address, '127.0.0.1'),
|
||||
pick($ec2_port, '8773'))
|
||||
} else {
|
||||
$ec2_internal_url_real = $ec2_internal_url
|
||||
}
|
||||
|
||||
if ($admin_protocol or $admin_address or $ec2_port) {
|
||||
$ec2_admin_url_real = sprintf('%s://%s:%s/services/Admin',
|
||||
pick($admin_protocol, 'http'),
|
||||
pick($admin_address, '127.0.0.1'),
|
||||
pick($ec2_port, '8773'))
|
||||
} else {
|
||||
$ec2_admin_url_real = $ec2_admin_url
|
||||
}
|
||||
|
||||
if $configure_endpoint {
|
||||
keystone_endpoint { "${region}/${auth_name}":
|
||||
ensure => present,
|
||||
public_url => "${public_protocol}://${public_address}:${compute_port}/${compute_version}/%(tenant_id)s",
|
||||
admin_url => "${admin_protocol}://${admin_address}:${compute_port}/${compute_version}/%(tenant_id)s",
|
||||
internal_url => "${internal_protocol}://${internal_address}:${compute_port}/${compute_version}/%(tenant_id)s",
|
||||
}
|
||||
Keystone_endpoint["${region}/${real_service_name}"] ~> Service <| name == 'nova-api' |>
|
||||
}
|
||||
|
||||
if $configure_ec2_endpoint {
|
||||
keystone_service { "${auth_name}_ec2":
|
||||
ensure => present,
|
||||
type => 'ec2',
|
||||
description => 'EC2 Service',
|
||||
}
|
||||
keystone_endpoint { "${region}/${auth_name}_ec2":
|
||||
ensure => present,
|
||||
public_url => "${public_protocol}://${public_address}:${ec2_port}/services/Cloud",
|
||||
admin_url => "${admin_protocol}://${admin_address}:${ec2_port}/services/Admin",
|
||||
internal_url => "${internal_protocol}://${internal_address}:${ec2_port}/services/Cloud",
|
||||
}
|
||||
keystone::resource::service_identity { "nova service, user ${auth_name}":
|
||||
configure_user => $configure_user,
|
||||
configure_user_role => $configure_user_role,
|
||||
configure_endpoint => $configure_endpoint,
|
||||
service_type => 'compute',
|
||||
service_description => 'Openstack Compute Service',
|
||||
service_name => $real_service_name,
|
||||
region => $region,
|
||||
auth_name => $auth_name,
|
||||
password => $password,
|
||||
email => $email,
|
||||
tenant => $tenant,
|
||||
public_url => $public_url_real,
|
||||
admin_url => $admin_url_real,
|
||||
internal_url => $internal_url_real,
|
||||
}
|
||||
|
||||
keystone::resource::service_identity { "nova v3 service, user ${auth_name_v3}":
|
||||
configure_user => false,
|
||||
configure_user_role => false,
|
||||
configure_endpoint => $configure_endpoint_v3,
|
||||
configure_service => $configure_endpoint_v3,
|
||||
service_type => 'computev3',
|
||||
service_description => 'Openstack Compute Service v3',
|
||||
service_name => $real_service_name_v3,
|
||||
region => $region,
|
||||
auth_name => $auth_name_v3,
|
||||
public_url => $public_url_v3,
|
||||
admin_url => $admin_url_v3,
|
||||
internal_url => $internal_url_v3,
|
||||
}
|
||||
|
||||
keystone::resource::service_identity { "nova ec2 service, user ${auth_name}_ec2":
|
||||
configure_user => false,
|
||||
configure_user_role => false,
|
||||
configure_endpoint => $configure_ec2_endpoint,
|
||||
configure_service => $configure_ec2_endpoint,
|
||||
service_type => 'ec2',
|
||||
service_description => 'EC2 Service',
|
||||
service_name => "${real_service_name}_ec2",
|
||||
region => $region,
|
||||
auth_name => "${auth_name}_ec2",
|
||||
public_url => $ec2_public_url_real,
|
||||
admin_url => $ec2_admin_url_real,
|
||||
internal_url => $ec2_internal_url_real,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
class nova::limits ($limits = {})
|
||||
{
|
||||
|
||||
$default_limits = {
|
||||
'POST' => 10,
|
||||
'POST_SERVERS' => 50,
|
||||
'PUT' => 10,
|
||||
'GET' => 3,
|
||||
'DELETE' => 100,
|
||||
}
|
||||
|
||||
$merged_limits = merge($default_limits, $limits)
|
||||
|
||||
$post_limit=$merged_limits[POST]
|
||||
$put_limit=$merged_limits[PUT]
|
||||
$get_limit=$merged_limits[GET]
|
||||
$delete_limit=$merged_limits[DELETE]
|
||||
$post_servers_limit=$merged_limits[POST_SERVERS]
|
||||
|
||||
Package<| title == 'nova-common' |> -> Nova_paste_api_ini<| |>
|
||||
|
||||
nova_paste_api_ini {'filter:ratelimit/limits': value => "(POST, \"*\", .*, ${post_limit}, MINUTE);(POST, \"*/servers\", ^/servers, ${post_servers_limit}, DAY);(PUT, \"*\", .*, ${put_limit}, MINUTE);(GET, \"*changes-since*\", .*changes-since.*, ${get_limit}, MINUTE);(DELETE, \"*\", .*, ${delete_limit}, MINUTE)"}
|
||||
}
|
208
deployment/puppet/nova/manifests/logging.pp
Normal file
208
deployment/puppet/nova/manifests/logging.pp
Normal file
@ -0,0 +1,208 @@
|
||||
# Class nova::logging
|
||||
#
|
||||
# nova extended logging configuration
|
||||
#
|
||||
# == parameters
|
||||
#
|
||||
# [*logging_context_format_string*]
|
||||
# (optional) Format string to use for log messages with context.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
|
||||
# [%(request_id)s %(user_identity)s] %(instance)s%(message)s'
|
||||
#
|
||||
# [*logging_default_format_string*]
|
||||
# (optional) Format string to use for log messages without context.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
|
||||
# [-] %(instance)s%(message)s'
|
||||
#
|
||||
# [*logging_debug_format_suffix*]
|
||||
# (optional) Formatted data to append to log format when level is DEBUG.
|
||||
# Defaults to undef.
|
||||
# Example: '%(funcName)s %(pathname)s:%(lineno)d'
|
||||
#
|
||||
# [*logging_exception_prefix*]
|
||||
# (optional) Prefix each line of exception output with this format.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s'
|
||||
#
|
||||
# [*log_config_append*]
|
||||
# The name of an additional logging configuration file.
|
||||
# Defaults to undef.
|
||||
# See https://docs.python.org/2/howto/logging.html
|
||||
#
|
||||
# [*default_log_levels*]
|
||||
# (optional) Hash of logger (keys) and level (values) pairs.
|
||||
# Defaults to undef.
|
||||
# Example:
|
||||
# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN',
|
||||
# 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO',
|
||||
# 'iso8601' => 'WARN',
|
||||
# 'requests.packages.urllib3.connectionpool' => 'WARN' }
|
||||
#
|
||||
# [*publish_errors*]
|
||||
# (optional) Publish error events (boolean value).
|
||||
# Defaults to undef (false if unconfigured).
|
||||
#
|
||||
# [*fatal_deprecations*]
|
||||
# (optional) Make deprecations fatal (boolean value)
|
||||
# Defaults to undef (false if unconfigured).
|
||||
#
|
||||
# [*instance_format*]
|
||||
# (optional) If an instance is passed with the log message, format it
|
||||
# like this (string value).
|
||||
# Defaults to undef.
|
||||
# Example: '[instance: %(uuid)s] '
|
||||
#
|
||||
# [*instance_uuid_format*]
|
||||
# (optional) If an instance UUID is passed with the log message, format
|
||||
# it like this (string value).
|
||||
# Defaults to undef.
|
||||
# Example: instance_uuid_format='[instance: %(uuid)s] '
|
||||
|
||||
# [*log_date_format*]
|
||||
# (optional) Format string for %%(asctime)s in log records.
|
||||
# Defaults to undef.
|
||||
# Example: 'Y-%m-%d %H:%M:%S'
|
||||
|
||||
class nova::logging(
|
||||
$logging_context_format_string = undef,
|
||||
$logging_default_format_string = undef,
|
||||
$logging_debug_format_suffix = undef,
|
||||
$logging_exception_prefix = undef,
|
||||
$log_config_append = undef,
|
||||
$default_log_levels = undef,
|
||||
$publish_errors = undef,
|
||||
$fatal_deprecations = undef,
|
||||
$instance_format = undef,
|
||||
$instance_uuid_format = undef,
|
||||
$log_date_format = undef,
|
||||
) {
|
||||
|
||||
if $logging_context_format_string {
|
||||
nova_config {
|
||||
'DEFAULT/logging_context_format_string' :
|
||||
value => $logging_context_format_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/logging_context_format_string' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_default_format_string {
|
||||
nova_config {
|
||||
'DEFAULT/logging_default_format_string' :
|
||||
value => $logging_default_format_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/logging_default_format_string' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_debug_format_suffix {
|
||||
nova_config {
|
||||
'DEFAULT/logging_debug_format_suffix' :
|
||||
value => $logging_debug_format_suffix;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/logging_debug_format_suffix' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_exception_prefix {
|
||||
nova_config {
|
||||
'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/logging_exception_prefix' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $log_config_append {
|
||||
nova_config {
|
||||
'DEFAULT/log_config_append' : value => $log_config_append;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/log_config_append' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $default_log_levels {
|
||||
nova_config {
|
||||
'DEFAULT/default_log_levels' :
|
||||
value => join(sort(join_keys_to_values($default_log_levels, '=')), ',');
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/default_log_levels' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $publish_errors {
|
||||
nova_config {
|
||||
'DEFAULT/publish_errors' : value => $publish_errors;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/publish_errors' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $fatal_deprecations {
|
||||
nova_config {
|
||||
'DEFAULT/fatal_deprecations' : value => $fatal_deprecations;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/fatal_deprecations' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $instance_format {
|
||||
nova_config {
|
||||
'DEFAULT/instance_format' : value => $instance_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/instance_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $instance_uuid_format {
|
||||
nova_config {
|
||||
'DEFAULT/instance_uuid_format' : value => $instance_uuid_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/instance_uuid_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $log_date_format {
|
||||
nova_config {
|
||||
'DEFAULT/log_date_format' : value => $log_date_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nova_config {
|
||||
'DEFAULT/log_date_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -1,21 +0,0 @@
|
||||
# Class for creating floating ip range
|
||||
# - ip_range = ['192.168.1.1-192.168.1.55','192.168.2.1-192.168.2.66']
|
||||
class nova::manage::floating_range (
|
||||
$ip_range,
|
||||
$pool = 'nova',
|
||||
$username = 'admin',
|
||||
$api_key = 'nova',
|
||||
$password = 'nova',
|
||||
$auth_url = undef,
|
||||
$authtenant_name = 'admin',
|
||||
){
|
||||
nova_floating_range{$ip_range:
|
||||
ensure => 'present',
|
||||
pool => $pool,
|
||||
username => $username,
|
||||
api_key => $api_key,
|
||||
auth_method => $password,
|
||||
auth_url => $auth_url,
|
||||
authtenant_name => $authtenant_name,
|
||||
}
|
||||
}
|
@ -25,8 +25,7 @@ define nova::manage::network (
|
||||
$num_networks = 1,
|
||||
$network_size = 255,
|
||||
$vlan_start = undef,
|
||||
$project = undef,
|
||||
$nameservers = ['8.8.8.8','8.8.4.4']
|
||||
$project = undef
|
||||
) {
|
||||
|
||||
File['/etc/nova/nova.conf'] -> Nova_network[$name]
|
||||
@ -40,8 +39,6 @@ define nova::manage::network (
|
||||
network_size => $network_size,
|
||||
project => $project,
|
||||
vlan_start => $vlan_start,
|
||||
dns1 => $nameservers[0],
|
||||
dns2 => $nameservers[1]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,9 +30,10 @@ class nova::migration::libvirt {
|
||||
}
|
||||
|
||||
file_line { '/etc/sysconfig/libvirtd libvirtd args':
|
||||
path => '/etc/sysconfig/libvirtd',
|
||||
line => 'LIBVIRTD_ARGS="--listen"',
|
||||
match => 'LIBVIRTD_ARGS=',
|
||||
path => '/etc/sysconfig/libvirtd',
|
||||
line => 'LIBVIRTD_ARGS="--listen"',
|
||||
match => 'LIBVIRTD_ARGS=',
|
||||
notify => Service['libvirt'],
|
||||
}
|
||||
|
||||
Package['libvirt'] -> File_line<| path == '/etc/sysconfig/libvirtd' |>
|
||||
@ -59,14 +60,14 @@ class nova::migration::libvirt {
|
||||
match => 'auth_tcp =',
|
||||
notify => Service['libvirt'],
|
||||
}
|
||||
|
||||
file_line { '/etc/default/libvirt-bin libvirtd opts':
|
||||
path => '/etc/default/libvirt-bin',
|
||||
line => 'libvirtd_opts="-d -l"',
|
||||
match => 'libvirtd_opts=',
|
||||
file_line { "/etc/default/${::nova::compute::libvirt::libvirt_service_name} libvirtd opts":
|
||||
path => "/etc/default/${::nova::compute::libvirt::libvirt_service_name}",
|
||||
line => 'libvirtd_opts="-d -l"',
|
||||
match => 'libvirtd_opts=',
|
||||
notify => Service['libvirt'],
|
||||
}
|
||||
|
||||
Package['libvirt'] -> File_line<| path == '/etc/default/libvirt-bin' |>
|
||||
Package['libvirt'] -> File_line<| path == "/etc/default/${::nova::compute::libvirt::libvirt_service_name}" |>
|
||||
}
|
||||
|
||||
default: {
|
||||
|
@ -1,8 +1,11 @@
|
||||
# == Class: nova::network
|
||||
#
|
||||
# Manages nova-network. Note that
|
||||
# Nova-network is not receiving upstream patches any more
|
||||
# and Neutron should be used in its place
|
||||
# Manages nova-network.
|
||||
#
|
||||
# An OpenStack deployment that includes compute and networking will use either
|
||||
# nova-network or Neutron. Neutron is newer and nova-network is the legacy
|
||||
# networking support built directly into Nova. However, nova-network is still
|
||||
# fully supported, is not feature frozen, and is not yet officially deprecated.
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
@ -23,6 +26,10 @@
|
||||
# split into.
|
||||
# Defaults to 1
|
||||
#
|
||||
# [*network_size*]
|
||||
# (optional) Number of addresses in each private subnet.
|
||||
# Defaults to 255
|
||||
#
|
||||
# [*floating_range*]
|
||||
# (optional) Range of floating ip addresses to create.
|
||||
# Defaults to false
|
||||
@ -64,11 +71,10 @@ class nova::network(
|
||||
$config_overrides = {},
|
||||
$create_networks = true,
|
||||
$ensure_package = 'present',
|
||||
$install_service = true,
|
||||
$nameservers = ['8.8.8.8','8.8.4.4']
|
||||
$install_service = true
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
# forward all ipv4 traffic
|
||||
# this is required for the vms to pass through the gateways
|
||||
@ -77,16 +83,7 @@ class nova::network(
|
||||
path => $::path
|
||||
}
|
||||
|
||||
# NOTE(bogdando) contribute change to upstream #1384145
|
||||
if !defined(Sysctl::Value['net.ipv4.ip_forward']) {
|
||||
sysctl::value { 'net.ipv4.ip_forward':
|
||||
value => '1'
|
||||
}
|
||||
} else {
|
||||
Sysctl::Value<| name == 'net.ipv4.ip_forward' |> {
|
||||
value => '1'
|
||||
}
|
||||
}
|
||||
ensure_resource('sysctl::value', 'net.ipv4.ip_forward', { value => '1' })
|
||||
|
||||
if $floating_range {
|
||||
nova_config { 'DEFAULT/floating_range': value => $floating_range }
|
||||
@ -110,11 +107,10 @@ class nova::network(
|
||||
|
||||
if $create_networks {
|
||||
nova::manage::network { 'nova-vm-net':
|
||||
network => $fixed_range,
|
||||
num_networks => $num_networks,
|
||||
network_size => $network_size,
|
||||
nameservers => $nameservers,
|
||||
vlan_start => $vlan_start,
|
||||
network => $fixed_range,
|
||||
num_networks => $num_networks,
|
||||
network_size => $network_size,
|
||||
vlan_start => $vlan_start,
|
||||
}
|
||||
if $floating_range {
|
||||
nova::manage::floating { 'nova-vm-floating':
|
||||
|
@ -7,7 +7,7 @@
|
||||
# [*fixed_range*]
|
||||
# (required) The IPv4 CIDR for the network
|
||||
#
|
||||
# [flat_interface]
|
||||
# [*flat_interface*]
|
||||
# (optional) Interface that flat network will use for bridging
|
||||
# Defaults to undef
|
||||
#
|
||||
@ -15,7 +15,7 @@
|
||||
# (optional) The interface to use for public traffic
|
||||
# Defaults to undef
|
||||
#
|
||||
# [flat_network_bridge]
|
||||
# [*flat_network_bridge*]
|
||||
# (optional) The name of the bridge to use
|
||||
# Defaults to 'br100'
|
||||
#
|
||||
|
@ -57,6 +57,11 @@
|
||||
# and not the Identity service API IP and port.
|
||||
# Defaults to 'http://127.0.0.1:35357/v2.0'
|
||||
#
|
||||
# [*network_api_class*]
|
||||
# (optional) The full class name of the network API class.
|
||||
# The default configures Nova to use Neutron for the network API.
|
||||
# Defaults to 'nova.network.neutronv2.api.API'
|
||||
#
|
||||
# [*security_group_api*]
|
||||
# (optional) The full class name of the security API class.
|
||||
# The default configures Nova to use Neutron for security groups.
|
||||
@ -82,6 +87,10 @@
|
||||
# notification is not being used.
|
||||
# Defaults to '300'
|
||||
#
|
||||
# [*dhcp_domain*]
|
||||
# (optional) domain to use for building the hostnames
|
||||
# Defaults to 'novalocal'
|
||||
#
|
||||
class nova::network::neutron (
|
||||
$neutron_admin_password,
|
||||
$neutron_auth_strategy = 'keystone',
|
||||
@ -95,35 +104,38 @@ class nova::network::neutron (
|
||||
$neutron_ovs_bridge = 'br-int',
|
||||
$neutron_extension_sync_interval = '600',
|
||||
$neutron_ca_certificates_file = undef,
|
||||
$network_api_class = 'nova.network.neutronv2.api.API',
|
||||
$security_group_api = 'neutron',
|
||||
$firewall_driver = 'nova.virt.firewall.NoopFirewallDriver',
|
||||
$vif_plugging_is_fatal = true,
|
||||
$vif_plugging_timeout = '300'
|
||||
$vif_plugging_timeout = '300',
|
||||
$dhcp_domain = 'novalocal',
|
||||
) {
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/neutron_auth_strategy': value => $neutron_auth_strategy;
|
||||
'DEFAULT/network_api_class': value => 'nova.network.neutronv2.api.API';
|
||||
'DEFAULT/neutron_url': value => $neutron_url;
|
||||
'DEFAULT/neutron_url_timeout': value => $neutron_url_timeout;
|
||||
'DEFAULT/neutron_admin_tenant_name': value => $neutron_admin_tenant_name;
|
||||
'DEFAULT/neutron_default_tenant_id': value => $neutron_default_tenant_id;
|
||||
'DEFAULT/neutron_region_name': value => $neutron_region_name;
|
||||
'DEFAULT/neutron_admin_username': value => $neutron_admin_username;
|
||||
'DEFAULT/neutron_admin_password': value => $neutron_admin_password, secret => true;
|
||||
'DEFAULT/neutron_admin_auth_url': value => $neutron_admin_auth_url;
|
||||
'DEFAULT/neutron_ovs_bridge': value => $neutron_ovs_bridge;
|
||||
'DEFAULT/neutron_extension_sync_interval': value => $neutron_extension_sync_interval;
|
||||
'DEFAULT/security_group_api': value => $security_group_api;
|
||||
'DEFAULT/firewall_driver': value => $firewall_driver;
|
||||
'DEFAULT/vif_plugging_is_fatal': value => $vif_plugging_is_fatal;
|
||||
'DEFAULT/vif_plugging_timeout': value => $vif_plugging_timeout;
|
||||
'DEFAULT/dhcp_domain': value => $dhcp_domain;
|
||||
'DEFAULT/firewall_driver': value => $firewall_driver;
|
||||
'DEFAULT/network_api_class': value => $network_api_class;
|
||||
'DEFAULT/security_group_api': value => $security_group_api;
|
||||
'DEFAULT/vif_plugging_is_fatal': value => $vif_plugging_is_fatal;
|
||||
'DEFAULT/vif_plugging_timeout': value => $vif_plugging_timeout;
|
||||
'neutron/auth_strategy': value => $neutron_auth_strategy;
|
||||
'neutron/url': value => $neutron_url;
|
||||
'neutron/url_timeout': value => $neutron_url_timeout;
|
||||
'neutron/admin_tenant_name': value => $neutron_admin_tenant_name;
|
||||
'neutron/default_tenant_id': value => $neutron_default_tenant_id;
|
||||
'neutron/region_name': value => $neutron_region_name;
|
||||
'neutron/admin_username': value => $neutron_admin_username;
|
||||
'neutron/admin_password': value => $neutron_admin_password, secret => true;
|
||||
'neutron/admin_auth_url': value => $neutron_admin_auth_url;
|
||||
'neutron/ovs_bridge': value => $neutron_ovs_bridge;
|
||||
'neutron/extension_sync_interval': value => $neutron_extension_sync_interval;
|
||||
}
|
||||
|
||||
if ! $neutron_ca_certificates_file {
|
||||
nova_config { 'DEFAULT/neutron_ca_certificates_file': ensure => absent }
|
||||
nova_config { 'neutron/ca_certificates_file': ensure => absent }
|
||||
} else {
|
||||
nova_config { 'DEFAULT/neutron_ca_certificates_file': value => $neutron_ca_certificates_file }
|
||||
nova_config { 'neutron/ca_certificates_file': value => $neutron_ca_certificates_file }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class nova::objectstore(
|
||||
$bind_address = '0.0.0.0'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
nova::generic_service { 'objectstore':
|
||||
enabled => $enabled,
|
||||
@ -35,7 +35,7 @@ class nova::objectstore(
|
||||
package_name => $::nova::params::objectstore_package_name,
|
||||
service_name => $::nova::params::objectstore_service_name,
|
||||
ensure_package => $ensure_package,
|
||||
require => User['nova'],
|
||||
require => Package['nova-common'],
|
||||
}
|
||||
|
||||
nova_config {
|
||||
|
@ -22,6 +22,7 @@ class nova::params {
|
||||
$scheduler_package_name = 'openstack-nova-scheduler'
|
||||
$tgt_package_name = 'scsi-target-utils'
|
||||
$vncproxy_package_name = 'openstack-nova-novncproxy'
|
||||
$serialproxy_package_name = 'openstack-nova-serialproxy'
|
||||
$spicehtml5proxy_package_name = 'openstack-nova-console'
|
||||
# service names
|
||||
$api_service_name = 'openstack-nova-api'
|
||||
@ -36,18 +37,22 @@ class nova::params {
|
||||
$scheduler_service_name = 'openstack-nova-scheduler'
|
||||
$tgt_service_name = 'tgtd'
|
||||
$vncproxy_service_name = 'openstack-nova-novncproxy'
|
||||
$serialproxy_service_name = 'openstack-nova-serialproxy'
|
||||
$spicehtml5proxy_service_name = 'openstack-nova-spicehtml5proxy'
|
||||
# redhat specific config defaults
|
||||
$root_helper = 'sudo nova-rootwrap'
|
||||
$lock_path = '/var/lib/nova/tmp'
|
||||
$nova_log_group = 'nova'
|
||||
case $::operatingsystem {
|
||||
'Fedora', 'RedHat': {
|
||||
'Fedora': {
|
||||
$special_service_provider = undef
|
||||
}
|
||||
'RedHat': {
|
||||
if ($::operatingsystemrelease < 7) {
|
||||
'RedHat', 'CentOS', 'Scientific', 'OracleLinux': {
|
||||
if (versioncmp($::operatingsystemmajrelease, '7') < 0) {
|
||||
$messagebus_service_name = 'messagebus'
|
||||
$special_service_provider = 'init'
|
||||
} else {
|
||||
$messagebus_service_name = 'dbus'
|
||||
$special_service_provider = undef
|
||||
}
|
||||
}
|
||||
@ -72,6 +77,7 @@ class nova::params {
|
||||
$objectstore_package_name = 'nova-objectstore'
|
||||
$scheduler_package_name = 'nova-scheduler'
|
||||
$tgt_package_name = 'tgt'
|
||||
$serialproxy_package_name = 'nova-serialproxy'
|
||||
# service names
|
||||
$api_service_name = 'nova-api'
|
||||
$cells_service_name = 'nova-cells'
|
||||
@ -83,8 +89,8 @@ class nova::params {
|
||||
$network_service_name = 'nova-network'
|
||||
$objectstore_service_name = 'nova-objectstore'
|
||||
$scheduler_service_name = 'nova-scheduler'
|
||||
$spicehtml5proxy_service_name = 'nova-spicehtml5proxy'
|
||||
$vncproxy_service_name = 'nova-novncproxy'
|
||||
$serialproxy_service_name = 'nova-serialproxy'
|
||||
$tgt_service_name = 'tgt'
|
||||
# debian specific nova config
|
||||
$root_helper = 'sudo nova-rootwrap'
|
||||
@ -92,15 +98,19 @@ class nova::params {
|
||||
case $::operatingsystem {
|
||||
'Debian': {
|
||||
$spicehtml5proxy_package_name = 'nova-consoleproxy'
|
||||
$spicehtml5proxy_service_name = 'nova-spicehtml5proxy'
|
||||
$vncproxy_package_name = 'nova-consoleproxy'
|
||||
# Use default provider on Debian
|
||||
$special_service_provider = undef
|
||||
$nova_log_group = 'nova'
|
||||
}
|
||||
default: {
|
||||
$spicehtml5proxy_package_name = 'nova-spiceproxy'
|
||||
$spicehtml5proxy_service_name = 'nova-spiceproxy'
|
||||
$vncproxy_package_name = 'nova-novncproxy'
|
||||
# some of the services need to be started form the special upstart provider
|
||||
$special_service_provider = 'upstart'
|
||||
$nova_log_group = 'adm'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
deployment/puppet/nova/manifests/policy.pp
Normal file
39
deployment/puppet/nova/manifests/policy.pp
Normal file
@ -0,0 +1,39 @@
|
||||
# == Class: nova::policy
|
||||
#
|
||||
# Configure the nova policies
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*policies*]
|
||||
# (optional) Set of policies to configure for nova
|
||||
# Example :
|
||||
# {
|
||||
# 'nova-context_is_admin' => {
|
||||
# 'key' => 'context_is_admin',
|
||||
# 'value' => 'true'
|
||||
# },
|
||||
# 'nova-default' => {
|
||||
# 'key' => 'default',
|
||||
# 'value' => 'rule:admin_or_owner'
|
||||
# }
|
||||
# }
|
||||
# Defaults to empty hash.
|
||||
#
|
||||
# [*policy_path*]
|
||||
# (optional) Path to the nova policy.json file
|
||||
# Defaults to /etc/nova/policy.json
|
||||
#
|
||||
class nova::policy (
|
||||
$policies = {},
|
||||
$policy_path = '/etc/nova/policy.json',
|
||||
) {
|
||||
|
||||
validate_hash($policies)
|
||||
|
||||
Openstacklib::Policy::Base {
|
||||
file_path => $policy_path,
|
||||
}
|
||||
|
||||
create_resources('openstacklib::policy::base', $policies)
|
||||
|
||||
}
|
@ -39,18 +39,18 @@ class nova::qpid(
|
||||
$service_ensure = 'running'
|
||||
|
||||
qpid_user { $user:
|
||||
password => $password,
|
||||
file => $file,
|
||||
realm => $realm,
|
||||
provider => 'saslpasswd2',
|
||||
require => Class['qpid::server'],
|
||||
password => $password,
|
||||
file => $file,
|
||||
realm => $realm,
|
||||
provider => 'saslpasswd2',
|
||||
require => Class['qpid::server'],
|
||||
}
|
||||
|
||||
} else {
|
||||
$service_ensure = 'stopped'
|
||||
}
|
||||
|
||||
class { 'qpid::server':
|
||||
class { '::qpid::server':
|
||||
service_ensure => $service_ensure
|
||||
}
|
||||
|
||||
|
@ -17,30 +17,50 @@
|
||||
# Defaults to 51200
|
||||
#
|
||||
# [*quota_volumes*]
|
||||
# (optional) Number of volumes
|
||||
# Defaults to 10
|
||||
# (optional) Deprecated. This parameter does nothing and will be removed.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_gigabytes*]
|
||||
# (optional) Amount of ephemeral disk storage in GB
|
||||
# Defaults to 1000
|
||||
# (optional) Deprecated. This parameter does nothing and will be removed.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_floating_ips*]
|
||||
# (optional) Number of floating IPs
|
||||
# Defaults to 10
|
||||
#
|
||||
# [*quota_fixed_ips*]
|
||||
# (optional) Number of fixed IPs (this should be at least the number of instances allowed)
|
||||
# Defaults to -1
|
||||
#
|
||||
# [*quota_metadata_items*]
|
||||
# (optional) Number of metadata items per instance
|
||||
# Defaults to 128
|
||||
#
|
||||
# [*quota_max_injected_files*]
|
||||
# (optional) Deprecated. Use quota_injected_files instead
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_max_injected_file_content_bytes*]
|
||||
# (optional) Deprecated. Use quota_injected_file_content_bytes instead
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_max_injected_file_path_bytes*]
|
||||
# (optional) Deprecated. Use quota_injected_file_path_bytes instead
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_injected_files*]
|
||||
# (optional) Number of files that can be injected per instance
|
||||
# Defaults to 5
|
||||
#
|
||||
# [*quota_max_injected_file_content_bytes*]
|
||||
# [*quota_injected_file_content_bytes*]
|
||||
# (optional) Maximum size in bytes of injected files
|
||||
# Defaults to 10240
|
||||
#
|
||||
# [*quota_max_injected_file_path_bytes*]
|
||||
# [*quota_injected_file_path_bytes*]
|
||||
# (optional) Deprecated. Use quota_injected_file_path_length instead
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*quota_injected_file_path_length*]
|
||||
# (optional) Maximum size in bytes of injected file path
|
||||
# Defaults to 255
|
||||
#
|
||||
@ -54,12 +74,16 @@
|
||||
#
|
||||
# [*quota_key_pairs*]
|
||||
# (optional) Number of key pairs
|
||||
# Defaults to 10
|
||||
# Defaults to 100
|
||||
#
|
||||
# [*reservation_expire*]
|
||||
# (optional) Time until reservations expire in seconds
|
||||
# Defaults to 86400
|
||||
#
|
||||
# [*until_refresh*]
|
||||
# (optional) Count of reservations until usage is refreshed
|
||||
# Defaults to 0
|
||||
#
|
||||
# [*max_age*]
|
||||
# (optional) Number of seconds between subsequent usage refreshes
|
||||
# Defaults to 0
|
||||
@ -72,38 +96,78 @@ class nova::quota(
|
||||
$quota_instances = 10,
|
||||
$quota_cores = 20,
|
||||
$quota_ram = 51200,
|
||||
$quota_volumes = 10,
|
||||
$quota_gigabytes = 1000,
|
||||
$quota_floating_ips = 10,
|
||||
$quota_fixed_ips = -1,
|
||||
$quota_metadata_items = 128,
|
||||
$quota_max_injected_files = 5,
|
||||
$quota_max_injected_file_content_bytes = 10240,
|
||||
$quota_max_injected_file_path_bytes = 255,
|
||||
$quota_injected_files = 5,
|
||||
$quota_injected_file_content_bytes = 10240,
|
||||
$quota_injected_file_path_length = 255,
|
||||
$quota_security_groups = 10,
|
||||
$quota_security_group_rules = 20,
|
||||
$quota_key_pairs = 10,
|
||||
$quota_key_pairs = 100,
|
||||
$reservation_expire = 86400,
|
||||
$until_refresh = 0,
|
||||
$max_age = 0,
|
||||
$quota_driver = 'nova.quota.DbQuotaDriver'
|
||||
$quota_driver = 'nova.quota.DbQuotaDriver',
|
||||
# DEPRECATED PARAMETERS
|
||||
$quota_volumes = undef,
|
||||
$quota_gigabytes = undef,
|
||||
$quota_max_injected_files = undef,
|
||||
$quota_injected_file_path_bytes = undef,
|
||||
$quota_max_injected_file_content_bytes = undef,
|
||||
$quota_max_injected_file_path_bytes = undef
|
||||
) {
|
||||
|
||||
if $quota_volumes {
|
||||
warning('The quota_volumes parameter is deprecated and has no effect.')
|
||||
}
|
||||
|
||||
if $quota_gigabytes {
|
||||
warning('The quota_gigabytes parameter is deprecated and has no effect.')
|
||||
}
|
||||
|
||||
if $quota_max_injected_files {
|
||||
warning('The quota_max_injected_files parameter is deprecated, use quota_injected_files instead.')
|
||||
$quota_injected_files_real = $quota_max_injected_files
|
||||
} else {
|
||||
$quota_injected_files_real = $quota_injected_files
|
||||
}
|
||||
|
||||
if $quota_max_injected_file_content_bytes {
|
||||
warning('The quota_max_injected_file_content_bytes is deprecated, use quota_injected_file_content_bytes instead.')
|
||||
$quota_injected_file_content_bytes_real = $quota_max_injected_file_content_bytes
|
||||
} else {
|
||||
$quota_injected_file_content_bytes_real = $quota_injected_file_content_bytes
|
||||
}
|
||||
|
||||
if $quota_max_injected_file_path_bytes {
|
||||
fail('The quota_max_injected_file_path_bytes parameter is deprecated, use quota_injected_file_path_length instead.')
|
||||
}
|
||||
|
||||
if $quota_injected_file_path_bytes {
|
||||
warning('The quota_injected_file_path_bytes parameter is deprecated, use quota_injected_file_path_length instead.')
|
||||
$quota_injected_file_path_length_real = $quota_injected_file_path_bytes
|
||||
} else {
|
||||
$quota_injected_file_path_length_real = $quota_injected_file_path_length
|
||||
}
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/quota_instances': value => $quota_instances;
|
||||
'DEFAULT/quota_cores': value => $quota_cores;
|
||||
'DEFAULT/quota_ram': value => $quota_ram;
|
||||
'DEFAULT/quota_volumes': value => $quota_volumes;
|
||||
'DEFAULT/quota_gigabytes': value => $quota_gigabytes;
|
||||
'DEFAULT/quota_floating_ips': value => $quota_floating_ips;
|
||||
'DEFAULT/quota_metadata_items': value => $quota_metadata_items;
|
||||
'DEFAULT/quota_max_injected_files': value => $quota_max_injected_files;
|
||||
'DEFAULT/quota_max_injected_file_content_bytes': value => $quota_max_injected_file_content_bytes;
|
||||
'DEFAULT/quota_max_injected_file_path_bytes': value => $quota_max_injected_file_path_bytes;
|
||||
'DEFAULT/quota_security_groups': value => $quota_security_groups;
|
||||
'DEFAULT/quota_security_group_rules': value => $quota_security_group_rules;
|
||||
'DEFAULT/quota_key_pairs': value => $quota_key_pairs;
|
||||
'DEFAULT/reservation_expire': value => $reservation_expire;
|
||||
'DEFAULT/max_age': value => $max_age;
|
||||
'DEFAULT/quota_driver': value => $quota_driver
|
||||
'DEFAULT/quota_instances': value => $quota_instances;
|
||||
'DEFAULT/quota_cores': value => $quota_cores;
|
||||
'DEFAULT/quota_ram': value => $quota_ram;
|
||||
'DEFAULT/quota_floating_ips': value => $quota_floating_ips;
|
||||
'DEFAULT/quota_fixed_ips': value => $quota_fixed_ips;
|
||||
'DEFAULT/quota_metadata_items': value => $quota_metadata_items;
|
||||
'DEFAULT/quota_injected_files': value => $quota_injected_files_real;
|
||||
'DEFAULT/quota_injected_file_content_bytes': value => $quota_injected_file_content_bytes_real;
|
||||
'DEFAULT/quota_injected_file_path_length': value => $quota_injected_file_path_length_real;
|
||||
'DEFAULT/quota_security_groups': value => $quota_security_groups;
|
||||
'DEFAULT/quota_security_group_rules': value => $quota_security_group_rules;
|
||||
'DEFAULT/quota_key_pairs': value => $quota_key_pairs;
|
||||
'DEFAULT/reservation_expire': value => $reservation_expire;
|
||||
'DEFAULT/until_refresh': value => $until_refresh;
|
||||
'DEFAULT/max_age': value => $max_age;
|
||||
'DEFAULT/quota_driver': value => $quota_driver
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,10 +30,10 @@
|
||||
# Defaults to false
|
||||
#
|
||||
# [*rabbitmq_class*]
|
||||
# (optional) The rabbitmq puppet class to depend on,
|
||||
# (optional) Deprecated. The rabbitmq puppet class to depend on,
|
||||
# which is dependent on the puppet-rabbitmq version.
|
||||
# Use the default for 1.x, use 'rabbitmq' for 3.x.
|
||||
# Use false, if rabbitmq class should not be configured
|
||||
# Use false if rabbitmq class should not be configured
|
||||
# here
|
||||
# Defaults to 'rabbitmq::server'
|
||||
#
|
||||
@ -44,6 +44,7 @@ class nova::rabbitmq(
|
||||
$virtual_host ='/',
|
||||
$cluster_disk_nodes = false,
|
||||
$enabled = true,
|
||||
# DEPRECATED PARAMETER
|
||||
$rabbitmq_class = 'rabbitmq::server'
|
||||
) {
|
||||
|
||||
@ -53,9 +54,9 @@ class nova::rabbitmq(
|
||||
} else {
|
||||
$delete_guest_user = true
|
||||
rabbitmq_user { $userid:
|
||||
admin => true,
|
||||
password => $password,
|
||||
provider => 'rabbitmqctl',
|
||||
admin => true,
|
||||
password => $password,
|
||||
provider => 'rabbitmqctl',
|
||||
}
|
||||
# I need to figure out the appropriate permissions
|
||||
rabbitmq_user_permissions { "${userid}@${virtual_host}":
|
||||
@ -70,9 +71,11 @@ class nova::rabbitmq(
|
||||
$service_ensure = 'stopped'
|
||||
}
|
||||
|
||||
# TODO(bogdando) contribute this to puppet-nova as they
|
||||
# do not want nova manage rabbitmq service anymore.
|
||||
# NOTE(bogdando) do not nova manage rabbitmq service
|
||||
# if rabbitmq_class is set to False
|
||||
if $rabbitmq_class {
|
||||
warning('The rabbitmq_class parameter is deprecated.')
|
||||
|
||||
if $cluster_disk_nodes {
|
||||
class { $rabbitmq_class:
|
||||
service_ensure => $service_ensure,
|
||||
|
@ -1,4 +1,4 @@
|
||||
# == Class: nova::schedule
|
||||
# == Class: nova::scheduler
|
||||
#
|
||||
# Install and manage nova scheduler
|
||||
#
|
||||
@ -22,7 +22,8 @@ class nova::scheduler(
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::db
|
||||
include ::nova::params
|
||||
|
||||
nova::generic_service { 'scheduler':
|
||||
enabled => $enabled,
|
||||
|
@ -40,7 +40,7 @@
|
||||
# (optional) Ignore hosts that have too many instances
|
||||
# Defaults to '50'
|
||||
#
|
||||
# [*ram_allocation_ratio:*]
|
||||
# [*ram_allocation_ratio*]
|
||||
# (optional) Virtual ram to physical ram allocation ratio
|
||||
# Defaults to '1.5'
|
||||
#
|
||||
@ -49,7 +49,7 @@
|
||||
# Defaults to 'nova.scheduler.filters.all_filters'
|
||||
#
|
||||
# [*scheduler_default_filters*]
|
||||
# (optional) A comma separated list of filters to be used by default
|
||||
# (optional) An array of filters to be used by default
|
||||
# Defaults to false
|
||||
#
|
||||
# [*scheduler_weight_classes*]
|
||||
|
50
deployment/puppet/nova/manifests/serialproxy.pp
Normal file
50
deployment/puppet/nova/manifests/serialproxy.pp
Normal file
@ -0,0 +1,50 @@
|
||||
# == Class: nova:serialproxy
|
||||
#
|
||||
# Configures nova serialproxy
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# [*enabled*]
|
||||
# (optional) Whether to run the serialproxy service
|
||||
# Defaults to false
|
||||
#
|
||||
# [*manage_service*]
|
||||
# (optional) Whether to start/stop the service
|
||||
# Defaults to true
|
||||
#
|
||||
# [*serialproxy_host*]
|
||||
# (optional) Host on which to listen for incoming requests
|
||||
# Defaults to '0.0.0.0'
|
||||
#
|
||||
# [*serialproxy_port*]
|
||||
# (optional) Port on which to listen for incoming requests
|
||||
# Defaults to '6083'
|
||||
#
|
||||
# [*ensure_package*]
|
||||
# (optional) The state of the nova-serialproxy package
|
||||
# Defaults to 'present'
|
||||
#
|
||||
class nova::serialproxy(
|
||||
$enabled = true,
|
||||
$manage_service = true,
|
||||
$serialproxy_host = '0.0.0.0',
|
||||
$serialproxy_port = '6083',
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include ::nova::params
|
||||
|
||||
nova_config {
|
||||
'serial_console/serialproxy_port': value => $serialproxy_port;
|
||||
'serial_console/serialproxy_host': value => $serialproxy_host;
|
||||
}
|
||||
|
||||
nova::generic_service { 'serialproxy':
|
||||
enabled => $enabled,
|
||||
manage_service => $manage_service,
|
||||
package_name => $::nova::params::serialproxy_package_name,
|
||||
service_name => $::nova::params::serialproxy_service_name,
|
||||
ensure_package => $ensure_package
|
||||
}
|
||||
|
||||
}
|
@ -36,11 +36,13 @@ class nova::spicehtml5proxy(
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
include ::nova::params
|
||||
|
||||
nova_config {
|
||||
'DEFAULT/spicehtml5proxy_host': value => $host;
|
||||
'DEFAULT/spicehtml5proxy_port': value => $port;
|
||||
'spice/enabled': value => $enabled;
|
||||
'spice/agent_enabled': value => $enabled;
|
||||
'spice/html5proxy_host': value => $host;
|
||||
'spice/html5proxy_port': value => $port;
|
||||
}
|
||||
|
||||
nova::generic_service { 'spicehtml5proxy':
|
||||
|
@ -13,9 +13,9 @@ class nova::utilities {
|
||||
}
|
||||
|
||||
file {'guestfs.seed':
|
||||
ensure => present,
|
||||
path => '/var/run/guestfs.seed',
|
||||
content => 'libguestfs0 libguestfs/update-appliance boolean true'
|
||||
ensure => present,
|
||||
path => '/var/run/guestfs.seed',
|
||||
content => 'libguestfs0 libguestfs/update-appliance boolean true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,17 +24,26 @@
|
||||
# (optional) The state of the nova-novncproxy package
|
||||
# Defaults to 'present'
|
||||
#
|
||||
# [*vncproxy_protocol*]
|
||||
# (optional) The protocol to communicate with the VNC proxy server
|
||||
# Defaults to 'http'
|
||||
#
|
||||
# [*vncproxy_path*]
|
||||
# (optional) The path at the end of the uri for communication with the VNC
|
||||
# proxy server
|
||||
# Defaults to '/vnc_auto.html'
|
||||
#
|
||||
class nova::vncproxy(
|
||||
$enabled = false,
|
||||
$manage_service = true,
|
||||
$host = '0.0.0.0',
|
||||
$port = '6080',
|
||||
$ensure_package = 'present'
|
||||
$enabled = false,
|
||||
$manage_service = true,
|
||||
$vncproxy_protocol = 'http',
|
||||
$host = '0.0.0.0',
|
||||
$port = '6080',
|
||||
$vncproxy_path = '/vnc_auto.html',
|
||||
$ensure_package = 'present'
|
||||
) {
|
||||
|
||||
include nova::params
|
||||
|
||||
# TODO make this work on Fedora
|
||||
include ::nova::params
|
||||
|
||||
# See http://nova.openstack.org/runnova/vncconsole.html for more details.
|
||||
|
||||
@ -43,6 +52,8 @@ class nova::vncproxy(
|
||||
'DEFAULT/novncproxy_port': value => $port;
|
||||
}
|
||||
|
||||
include ::nova::vncproxy::common
|
||||
|
||||
if ! defined(Package['python-numpy']) {
|
||||
package { 'python-numpy':
|
||||
ensure => present,
|
||||
|
54
deployment/puppet/nova/manifests/vncproxy/common.pp
Normal file
54
deployment/puppet/nova/manifests/vncproxy/common.pp
Normal file
@ -0,0 +1,54 @@
|
||||
# == Class: nova::vncproxy::common
|
||||
#
|
||||
# [*vncproxy_host*]
|
||||
# (optional) The host of the VNC proxy server
|
||||
# Defaults to false
|
||||
#
|
||||
# [*vncproxy_protocol*]
|
||||
# (optional) The protocol to communicate with the VNC proxy server
|
||||
# Defaults to 'http'
|
||||
#
|
||||
# [*vncproxy_port*]
|
||||
# (optional) The port to communicate with the VNC proxy server
|
||||
# Defaults to '6080'
|
||||
#
|
||||
# [*vncproxy_path*]
|
||||
# (optional) The path at the end of the uri for communication with the VNC proxy server
|
||||
# Defaults to '/vnc_auto.html'
|
||||
#
|
||||
class nova::vncproxy::common (
|
||||
$vncproxy_host = undef,
|
||||
$vncproxy_protocol = undef,
|
||||
$vncproxy_port = undef,
|
||||
$vncproxy_path = undef,
|
||||
) {
|
||||
|
||||
$vncproxy_host_real = pick(
|
||||
$vncproxy_host,
|
||||
$::nova::compute::vncproxy_host,
|
||||
$::nova::vncproxy::host,
|
||||
false)
|
||||
$vncproxy_protocol_real = pick(
|
||||
$vncproxy_protocol,
|
||||
$::nova::compute::vncproxy_protocol,
|
||||
$::nova::vncproxy::vncproxy_protocol,
|
||||
'http')
|
||||
$vncproxy_port_real = pick(
|
||||
$vncproxy_port,
|
||||
$::nova::compute::vncproxy_port,
|
||||
$::nova::vncproxy::port,
|
||||
6080)
|
||||
$vncproxy_path_real = pick(
|
||||
$vncproxy_path,
|
||||
$::nova::compute::vncproxy_path,
|
||||
$::nova::vncproxy::vncproxy_path,
|
||||
'/vnc_auto.html')
|
||||
|
||||
if ($vncproxy_host_real) {
|
||||
$vncproxy_base_url = "${vncproxy_protocol_real}://${vncproxy_host_real}:${vncproxy_port_real}${vncproxy_path_real}"
|
||||
# config for vnc proxy
|
||||
nova_config {
|
||||
'DEFAULT/novncproxy_base_url': value => $vncproxy_base_url;
|
||||
}
|
||||
}
|
||||
}
|
44
deployment/puppet/nova/metadata.json
Normal file
44
deployment/puppet/nova/metadata.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "stackforge-nova",
|
||||
"version": "5.1.0",
|
||||
"author": "Puppet Labs and OpenStack Contributors",
|
||||
"summary": "Puppet module for OpenStack Nova",
|
||||
"license": "Apache-2.0",
|
||||
"source": "git://github.com/openstack/puppet-nova.git",
|
||||
"project_page": "https://launchpad.net/puppet-nova",
|
||||
"issues_url": "https://bugs.launchpad.net/puppet-nova",
|
||||
"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 Nova (Compute).",
|
||||
"dependencies": [
|
||||
{ "name": "dprince/qpid", "version_requirement": ">=1.0.0 <2.0.0" },
|
||||
{ "name": "duritong/sysctl", "version_requirement": ">=0.0.1 <1.0.0" },
|
||||
{ "name": "stackforge/cinder", "version_requirement": ">=5.0.0 <6.0.0" },
|
||||
{ "name": "stackforge/glance", "version_requirement": ">=5.0.0 <6.0.0" },
|
||||
{ "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" },
|
||||
{ "name": "stackforge/keystone", "version_requirement": ">=5.0.0 <6.0.0" },
|
||||
{ "name": "puppetlabs/rabbitmq", "version_requirement": ">=2.0.2 <4.0.0" },
|
||||
{ "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" },
|
||||
{ "name": "stackforge/openstacklib", "version_requirement": ">=5.0.0 <6.0.0" }
|
||||
]
|
||||
}
|
156
deployment/puppet/nova/spec/acceptance/basic_nova_spec.rb
Normal file
156
deployment/puppet/nova/spec/acceptance/basic_nova_spec.rb
Normal file
@ -0,0 +1,156 @@
|
||||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'basic nova' do
|
||||
|
||||
context 'default parameters' do
|
||||
|
||||
it 'should work with no errors' do
|
||||
pp= <<-EOS
|
||||
Exec { logoutput => 'on_failure' }
|
||||
|
||||
# Common resources
|
||||
case $::osfamily {
|
||||
'Debian': {
|
||||
include ::apt
|
||||
class { '::openstack_extras::repo::debian::ubuntu':
|
||||
release => 'kilo',
|
||||
package_require => true,
|
||||
}
|
||||
$package_provider = 'apt'
|
||||
}
|
||||
'RedHat': {
|
||||
class { '::openstack_extras::repo::redhat::redhat':
|
||||
# Kilo is not GA yet, so let's use the testing repo
|
||||
manage_rdo => false,
|
||||
repo_hash => {
|
||||
'rdo-kilo-testing' => {
|
||||
'baseurl' => 'https://repos.fedorapeople.org/repos/openstack/openstack-kilo/testing/el7/',
|
||||
# packages are not GA so not signed
|
||||
'gpgcheck' => '0',
|
||||
'priority' => 97,
|
||||
},
|
||||
},
|
||||
}
|
||||
$package_provider = 'yum'
|
||||
}
|
||||
default: {
|
||||
fail("Unsupported osfamily (${::osfamily})")
|
||||
}
|
||||
}
|
||||
|
||||
class { '::mysql::server': }
|
||||
|
||||
class { '::rabbitmq':
|
||||
delete_guest_user => true,
|
||||
erlang_cookie => 'secrete',
|
||||
package_provider => $package_provider,
|
||||
}
|
||||
|
||||
rabbitmq_vhost { '/':
|
||||
provider => 'rabbitmqctl',
|
||||
require => Class['rabbitmq'],
|
||||
}
|
||||
|
||||
rabbitmq_user { 'nova':
|
||||
admin => true,
|
||||
password => 'an_even_bigger_secret',
|
||||
provider => 'rabbitmqctl',
|
||||
require => Class['rabbitmq'],
|
||||
}
|
||||
|
||||
rabbitmq_user_permissions { 'nova@/':
|
||||
configure_permission => '.*',
|
||||
write_permission => '.*',
|
||||
read_permission => '.*',
|
||||
provider => 'rabbitmqctl',
|
||||
require => Class['rabbitmq'],
|
||||
}
|
||||
|
||||
# Keystone resources, needed by Nova to run
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
admin_token => 'admin_token',
|
||||
enabled => true,
|
||||
}
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@example.tld',
|
||||
password => 'a_big_secret',
|
||||
}
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "https://${::fqdn}:5000/",
|
||||
admin_url => "https://${::fqdn}:35357/",
|
||||
}
|
||||
|
||||
# Nova resources
|
||||
class { '::nova':
|
||||
database_connection => 'mysql://nova:a_big_secret@127.0.0.1/nova?charset=utf8',
|
||||
rabbit_userid => 'nova',
|
||||
rabbit_password => 'an_even_bigger_secret',
|
||||
image_service => 'nova.image.glance.GlanceImageService',
|
||||
glance_api_servers => 'localhost:9292',
|
||||
verbose => false,
|
||||
rabbit_host => '127.0.0.1',
|
||||
}
|
||||
class { '::nova::db::mysql':
|
||||
password => 'a_big_secret',
|
||||
}
|
||||
class { '::nova::keystone::auth':
|
||||
password => 'a_big_secret',
|
||||
}
|
||||
class { '::nova::api':
|
||||
enabled => true,
|
||||
admin_password => 'a_big_secret',
|
||||
identity_uri => 'http://127.0.0.1:35357/',
|
||||
osapi_v3 => true,
|
||||
}
|
||||
class { '::nova::cert': enabled => true }
|
||||
class { '::nova::client': }
|
||||
class { '::nova::conductor': enabled => true }
|
||||
class { '::nova::consoleauth': enabled => true }
|
||||
class { '::nova::cron::archive_deleted_rows': }
|
||||
class { '::nova::compute':
|
||||
enabled => true,
|
||||
vnc_enabled => true,
|
||||
}
|
||||
class { '::nova::compute::libvirt':
|
||||
migration_support => true,
|
||||
vncserver_listen => '0.0.0.0',
|
||||
}
|
||||
class { '::nova::scheduler': enabled => true }
|
||||
class { '::nova::vncproxy': enabled => true }
|
||||
# TODO: networking with neutron
|
||||
EOS
|
||||
|
||||
|
||||
# Run it twice and test for idempotency
|
||||
apply_manifest(pp, :catch_failures => true)
|
||||
apply_manifest(pp, :catch_changes => true)
|
||||
end
|
||||
|
||||
describe port(8773) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe port(8774) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe port(8775) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe port(6080) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe cron do
|
||||
it { should have_entry('1 0 * * * nova-manage db archive_deleted_rows --max_rows 100 >>/var/log/nova/nova-rowsflush.log 2>&1').with_user('nova') }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
11
deployment/puppet/nova/spec/acceptance/nodesets/default.yml
Normal file
11
deployment/puppet/nova/spec/acceptance/nodesets/default.yml
Normal file
@ -0,0 +1,11 @@
|
||||
HOSTS:
|
||||
ubuntu-server-1404-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
box : puppetlabs/ubuntu-14.04-64-nocm
|
||||
box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
log_level : debug
|
||||
type: git
|
@ -0,0 +1,10 @@
|
||||
HOSTS:
|
||||
centos-70-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: el-7-x86_64
|
||||
hypervisor : none
|
||||
ip: 127.0.0.1
|
||||
CONFIG:
|
||||
type: foss
|
||||
set_env: false
|
@ -0,0 +1,10 @@
|
||||
HOSTS:
|
||||
ubuntu-14.04-amd64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
hypervisor : none
|
||||
ip: 127.0.0.1
|
||||
CONFIG:
|
||||
type: foss
|
||||
set_env: false
|
@ -0,0 +1,11 @@
|
||||
HOSTS:
|
||||
ubuntu-server-1404-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
box : puppetlabs/ubuntu-14.04-64-nocm
|
||||
box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm
|
||||
hypervisor : vagrant
|
||||
CONFIG:
|
||||
log_level : debug
|
||||
type: git
|
@ -19,64 +19,59 @@ describe 'nova::api' do
|
||||
context 'with default parameters' do
|
||||
|
||||
it 'installs nova-api package and service' do
|
||||
should contain_service('nova-api').with(
|
||||
is_expected.to contain_service('nova-api').with(
|
||||
:name => platform_params[:nova_api_service],
|
||||
:ensure => 'stopped',
|
||||
:hasstatus => true,
|
||||
:enable => false
|
||||
)
|
||||
should contain_package('nova-api').with(
|
||||
is_expected.to contain_package('nova-api').with(
|
||||
:name => platform_params[:nova_api_package],
|
||||
:ensure => 'present',
|
||||
:notify => 'Service[nova-api]'
|
||||
:tag => ['openstack']
|
||||
)
|
||||
is_expected.to contain_package('nova-api').that_notifies('Service[nova-api]')
|
||||
is_expected.to_not contain_exec('validate_nova_api')
|
||||
end
|
||||
|
||||
it 'configures keystone_authtoken middleware' do
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_host').with_value('127.0.0.1')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_port').with_value('35357')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_protocol').with_value('http')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_uri').with_value('http://127.0.0.1:5000/')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_admin_prefix').with_ensure('absent')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_version').with_ensure('absent')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_tenant_name').with_value('services')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_user').with_value('nova')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_password').with_value('passw0rd').with_secret(true)
|
||||
end
|
||||
|
||||
it 'configures various stuff' do
|
||||
should contain_nova_config('DEFAULT/ec2_listen').with('value' => '0.0.0.0')
|
||||
should contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '0.0.0.0')
|
||||
should contain_nova_config('DEFAULT/metadata_listen').with('value' => '0.0.0.0')
|
||||
should contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '0.0.0.0')
|
||||
should contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '5')
|
||||
should contain_nova_config('DEFAULT/metadata_workers').with('value' => '5')
|
||||
should contain_nova_config('conductor/workers').with('value' => '5')
|
||||
is_expected.to contain_nova_config('DEFAULT/ec2_listen').with('value' => '0.0.0.0')
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '0.0.0.0')
|
||||
is_expected.to contain_nova_config('DEFAULT/metadata_listen').with('value' => '0.0.0.0')
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '0.0.0.0')
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '5')
|
||||
is_expected.to contain_nova_config('DEFAULT/ec2_workers').with('value' => '5')
|
||||
is_expected.to contain_nova_config('DEFAULT/metadata_workers').with('value' => '5')
|
||||
end
|
||||
|
||||
it 'do not configure v3 api' do
|
||||
is_expected.to contain_nova_config('osapi_v3/enabled').with('value' => false)
|
||||
end
|
||||
|
||||
it 'unconfigures neutron_metadata proxy' do
|
||||
should contain_nova_config('DEFAULT/service_neutron_metadata_proxy').with(:value => false)
|
||||
should contain_nova_config('DEFAULT/neutron_metadata_proxy_shared_secret').with(:ensure => 'absent')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with deprecated parameters' do
|
||||
before do
|
||||
params.merge!({
|
||||
:workers => 1,
|
||||
})
|
||||
end
|
||||
it 'configures various stuff' do
|
||||
should contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '1')
|
||||
is_expected.to contain_nova_config('neutron/service_metadata_proxy').with(:value => false)
|
||||
is_expected.to contain_nova_config('neutron/metadata_proxy_shared_secret').with(:ensure => 'absent')
|
||||
end
|
||||
end
|
||||
|
||||
@ -102,16 +97,19 @@ describe 'nova::api' do
|
||||
:neutron_metadata_proxy_shared_secret => 'secrete',
|
||||
:osapi_compute_workers => 1,
|
||||
:metadata_workers => 2,
|
||||
:conductor_workers => 3,
|
||||
:osapi_v3 => true,
|
||||
:keystone_ec2_url => 'https://example.com:5000/v2.0/ec2tokens',
|
||||
:pci_alias => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]"
|
||||
})
|
||||
end
|
||||
|
||||
it 'installs nova-api package and service' do
|
||||
should contain_package('nova-api').with(
|
||||
is_expected.to contain_package('nova-api').with(
|
||||
:name => platform_params[:nova_api_package],
|
||||
:ensure => '2012.1-2'
|
||||
:ensure => '2012.1-2',
|
||||
:tag => ['openstack']
|
||||
)
|
||||
should contain_service('nova-api').with(
|
||||
is_expected.to contain_service('nova-api').with(
|
||||
:name => platform_params[:nova_api_service],
|
||||
:ensure => 'running',
|
||||
:hasstatus => true,
|
||||
@ -120,39 +118,49 @@ describe 'nova::api' do
|
||||
end
|
||||
|
||||
it 'configures keystone_authtoken middleware' do
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_host').with_value('10.0.0.1')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_port').with_value('1234')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_protocol').with_value('https')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_admin_prefix').with_value('/keystone/admin')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_uri').with_value('https://10.0.0.1:9999/')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/auth_version').with_value('v3.0')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_tenant_name').with_value('service2')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_user').with_value('nova2')
|
||||
should contain_nova_config(
|
||||
is_expected.to contain_nova_config(
|
||||
'keystone_authtoken/admin_password').with_value('passw0rd2').with_secret(true)
|
||||
should contain_nova_paste_api_ini(
|
||||
is_expected.to contain_nova_paste_api_ini(
|
||||
'filter:ratelimit/limits').with_value('(GET, "*", .*, 100, MINUTE);(POST, "*", .*, 200, MINUTE)')
|
||||
end
|
||||
|
||||
it 'configures various stuff' do
|
||||
should contain_nova_config('DEFAULT/ec2_listen').with('value' => '192.168.56.210')
|
||||
should contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '192.168.56.210')
|
||||
should contain_nova_config('DEFAULT/metadata_listen').with('value' => '127.0.0.1')
|
||||
should contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '192.168.56.210')
|
||||
should contain_nova_config('DEFAULT/use_forwarded_for').with('value' => false)
|
||||
should contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '1')
|
||||
should contain_nova_config('DEFAULT/metadata_workers').with('value' => '2')
|
||||
should contain_nova_config('conductor/workers').with('value' => '3')
|
||||
should contain_nova_config('DEFAULT/service_neutron_metadata_proxy').with('value' => true)
|
||||
should contain_nova_config('DEFAULT/neutron_metadata_proxy_shared_secret').with('value' => 'secrete')
|
||||
is_expected.to contain_nova_config('DEFAULT/ec2_listen').with('value' => '192.168.56.210')
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '192.168.56.210')
|
||||
is_expected.to contain_nova_config('DEFAULT/metadata_listen').with('value' => '127.0.0.1')
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '192.168.56.210')
|
||||
is_expected.to contain_nova_config('DEFAULT/use_forwarded_for').with('value' => false)
|
||||
is_expected.to contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '1')
|
||||
is_expected.to contain_nova_config('DEFAULT/metadata_workers').with('value' => '2')
|
||||
is_expected.to contain_nova_config('neutron/service_metadata_proxy').with('value' => true)
|
||||
is_expected.to contain_nova_config('neutron/metadata_proxy_shared_secret').with('value' => 'secrete')
|
||||
is_expected.to contain_nova_config('DEFAULT/keystone_ec2_url').with('value' => 'https://example.com:5000/v2.0/ec2tokens')
|
||||
end
|
||||
|
||||
it 'configure nova api v3' do
|
||||
is_expected.to contain_nova_config('osapi_v3/enabled').with('value' => true)
|
||||
end
|
||||
|
||||
it 'configures nova pci_alias entries' do
|
||||
is_expected.to contain_nova_config('DEFAULT/pci_alias').with(
|
||||
'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -168,11 +176,50 @@ describe 'nova::api' do
|
||||
before do
|
||||
params.merge!({ :auth_admin_prefix => auth_admin_prefix })
|
||||
end
|
||||
it { expect { should contain_nova_config('keystone_authtoken/auth_admin_prefix') }.to \
|
||||
it { expect { is_expected.to contain_nova_config('keystone_authtoken/auth_admin_prefix') }.to \
|
||||
raise_error(Puppet::Error, /validate_re\(\): "#{auth_admin_prefix}" does not match/) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'while validating the service with default command' do
|
||||
before do
|
||||
params.merge!({
|
||||
:validate => true,
|
||||
})
|
||||
end
|
||||
it { is_expected.to contain_exec('execute nova-api validation').with(
|
||||
:path => '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||
:provider => 'shell',
|
||||
:tries => '10',
|
||||
:try_sleep => '2',
|
||||
:command => 'nova --os-auth-url http://127.0.0.1:5000/ --os-tenant-name services --os-username nova --os-password passw0rd flavor-list',
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_anchor('create nova-api anchor').with(
|
||||
:require => 'Exec[execute nova-api validation]',
|
||||
)}
|
||||
end
|
||||
|
||||
context 'while validating the service with custom command' do
|
||||
before do
|
||||
params.merge!({
|
||||
:validate => true,
|
||||
:validation_options => { 'nova-api' => { 'command' => 'my-script' } }
|
||||
})
|
||||
end
|
||||
it { is_expected.to contain_exec('execute nova-api validation').with(
|
||||
:path => '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||
:provider => 'shell',
|
||||
:tries => '10',
|
||||
:try_sleep => '2',
|
||||
:command => 'my-script',
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_anchor('create nova-api anchor').with(
|
||||
:require => 'Exec[execute nova-api validation]',
|
||||
)}
|
||||
end
|
||||
|
||||
context 'while not managing service state' do
|
||||
before do
|
||||
params.merge!({
|
||||
@ -181,8 +228,67 @@ describe 'nova::api' do
|
||||
})
|
||||
end
|
||||
|
||||
it { should contain_service('nova-api').without_ensure }
|
||||
it { is_expected.to contain_service('nova-api').without_ensure }
|
||||
end
|
||||
|
||||
context 'with default database parameters' do
|
||||
let :pre_condition do
|
||||
"include nova"
|
||||
end
|
||||
|
||||
it { is_expected.to_not contain_nova_config('database/connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/slave_connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/idle_timeout').with_value('3600') }
|
||||
end
|
||||
|
||||
context 'with overridden database parameters' do
|
||||
let :pre_condition do
|
||||
"class { 'nova':
|
||||
database_connection => 'mysql://user:pass@db/db',
|
||||
slave_connection => 'mysql://user:pass@slave/db',
|
||||
database_idle_timeout => '30',
|
||||
}
|
||||
"
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('database/connection').with_value('mysql://user:pass@db/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql://user:pass@slave/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/idle_timeout').with_value('30') }
|
||||
end
|
||||
|
||||
context 'with custom keystone identity_uri' do
|
||||
before do
|
||||
params.merge!({
|
||||
:identity_uri => 'https://foo.bar:1234/',
|
||||
})
|
||||
end
|
||||
it 'configures identity_uri' do
|
||||
is_expected.to contain_nova_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:1234/");
|
||||
# since only auth_uri is set the deprecated auth parameters is_expected.to
|
||||
# still get set in case they are still in use
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_host').with_value('127.0.0.1');
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_port').with_value('35357');
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_protocol').with_value('http');
|
||||
end
|
||||
end
|
||||
|
||||
context 'with custom keystone identity_uri and auth_uri' do
|
||||
before do
|
||||
params.merge!({
|
||||
:identity_uri => 'https://foo.bar:35357/',
|
||||
:auth_uri => 'https://foo.bar:5000/v2.0/',
|
||||
})
|
||||
end
|
||||
it 'configures identity_uri' do
|
||||
is_expected.to contain_nova_config('keystone_authtoken/identity_uri').with_value("https://foo.bar:35357/");
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_uri').with_value("https://foo.bar:5000/v2.0/");
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_host').with_ensure('absent')
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_port').with_ensure('absent')
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_protocol').with_ensure('absent')
|
||||
is_expected.to contain_nova_config('keystone_authtoken/auth_admin_prefix').with_ensure('absent')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'on Debian platforms' do
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -55,43 +55,44 @@ describe 'nova::cells' do
|
||||
|
||||
shared_examples_for 'nova-cells' do
|
||||
|
||||
it { should contain_class('nova::params') }
|
||||
it { is_expected.to contain_class('nova::params') }
|
||||
|
||||
it 'installs nova-cells package' do
|
||||
should contain_package('nova-cells').with(
|
||||
is_expected.to contain_package('nova-cells').with(
|
||||
:ensure => 'present',
|
||||
:name => platform_params[:cells_package_name]
|
||||
:name => platform_params[:cells_package_name],
|
||||
:tag => ['openstack']
|
||||
)
|
||||
end
|
||||
|
||||
it 'configures nova-cells service' do
|
||||
should contain_service('nova-cells').with(
|
||||
is_expected.to contain_service('nova-cells').with(
|
||||
:ensure => 'running',
|
||||
:name => platform_params[:cells_service_name]
|
||||
)
|
||||
end
|
||||
|
||||
it 'configures cell' do
|
||||
should contain_nova_config('cells/bandwidth_update_interval').with(:value => '600')
|
||||
should contain_nova_config('cells/call_timeout').with(:value => '60')
|
||||
should contain_nova_config('cells/capabilities').with(:value => 'hypervisor=xenserver;kvm,os=linux;windows')
|
||||
should contain_nova_config('cells/db_check_interval').with(:value => '60')
|
||||
should contain_nova_config('cells/driver').with(:value => 'nova.cells.rpc_driver.CellsRPCDriver')
|
||||
should contain_nova_config('cells/instance_updated_at_threshold').with(:value => '3600')
|
||||
should contain_nova_config('cells/instance_update_num_instances').with(:value => '1')
|
||||
should contain_nova_config('cells/manager').with(:value => 'nova.cells.manager.CellsManager')
|
||||
should contain_nova_config('cells/max_hop_count').with(:value => '10')
|
||||
should contain_nova_config('cells/mute_child_interval').with(:value => '300')
|
||||
should contain_nova_config('cells/mute_weight_multiplier').with(:value => '-10.0')
|
||||
should contain_nova_config('cells/mute_weight_value').with(:value => '1000.0')
|
||||
should contain_nova_config('cells/ram_weight_multiplier').with(:value => '10.0')
|
||||
should contain_nova_config('cells/reserve_percent').with(:value => '10.0')
|
||||
should contain_nova_config('cells/rpc_driver_queue_base').with(:value => 'cells.intercell')
|
||||
should contain_nova_config('cells/scheduler_filter_classes').with(:value => 'nova.cells.filters.all_filters')
|
||||
should contain_nova_config('cells/scheduler_retries').with(:value => '10')
|
||||
should contain_nova_config('cells/scheduler_retry_delay').with(:value => '2')
|
||||
should contain_nova_config('cells/scheduler_weight_classes').with(:value => 'nova.cells.weights.all_weighers')
|
||||
should contain_nova_config('cells/scheduler').with(:value => 'nova.cells.scheduler.CellsScheduler')
|
||||
is_expected.to contain_nova_config('cells/bandwidth_update_interval').with(:value => '600')
|
||||
is_expected.to contain_nova_config('cells/call_timeout').with(:value => '60')
|
||||
is_expected.to contain_nova_config('cells/capabilities').with(:value => 'hypervisor=xenserver;kvm,os=linux;windows')
|
||||
is_expected.to contain_nova_config('cells/db_check_interval').with(:value => '60')
|
||||
is_expected.to contain_nova_config('cells/driver').with(:value => 'nova.cells.rpc_driver.CellsRPCDriver')
|
||||
is_expected.to contain_nova_config('cells/instance_updated_at_threshold').with(:value => '3600')
|
||||
is_expected.to contain_nova_config('cells/instance_update_num_instances').with(:value => '1')
|
||||
is_expected.to contain_nova_config('cells/manager').with(:value => 'nova.cells.manager.CellsManager')
|
||||
is_expected.to contain_nova_config('cells/max_hop_count').with(:value => '10')
|
||||
is_expected.to contain_nova_config('cells/mute_child_interval').with(:value => '300')
|
||||
is_expected.to contain_nova_config('cells/mute_weight_multiplier').with(:value => '-10.0')
|
||||
is_expected.to contain_nova_config('cells/mute_weight_value').with(:value => '1000.0')
|
||||
is_expected.to contain_nova_config('cells/ram_weight_multiplier').with(:value => '10.0')
|
||||
is_expected.to contain_nova_config('cells/reserve_percent').with(:value => '10.0')
|
||||
is_expected.to contain_nova_config('cells/rpc_driver_queue_base').with(:value => 'cells.intercell')
|
||||
is_expected.to contain_nova_config('cells/scheduler_filter_classes').with(:value => 'nova.cells.filters.all_filters')
|
||||
is_expected.to contain_nova_config('cells/scheduler_retries').with(:value => '10')
|
||||
is_expected.to contain_nova_config('cells/scheduler_retry_delay').with(:value => '2')
|
||||
is_expected.to contain_nova_config('cells/scheduler_weight_classes').with(:value => 'nova.cells.weights.all_weighers')
|
||||
is_expected.to contain_nova_config('cells/scheduler').with(:value => 'nova.cells.scheduler.CellsScheduler')
|
||||
end
|
||||
end
|
||||
|
||||
@ -104,8 +105,9 @@ describe 'nova::cells' do
|
||||
let :expected_params do
|
||||
default_params.merge(params)
|
||||
end
|
||||
it { should contain_nova_config('cells/name').with_value(expected_params[:cell_name]) }
|
||||
it { should contain_nova_config('DEFAULT/compute_api_class').with_value('nova.compute.cells_api.ComputeCellsAPI')}
|
||||
it { is_expected.to contain_nova_config('cells/name').with_value(expected_params[:cell_name]) }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/compute_api_class').with_value('nova.compute.cells_api.ComputeCellsAPI')}
|
||||
it { is_expected.to contain_nova_config('cells/cell_type').with_value('api')}
|
||||
it_configures 'nova-cells'
|
||||
end
|
||||
|
||||
@ -119,7 +121,7 @@ describe 'nova::cells' do
|
||||
let :expected_params do
|
||||
default_params.merge(params)
|
||||
end
|
||||
it { should contain_service(platform_params[:cells_service_name]).without_ensure }
|
||||
it { is_expected.to contain_service(platform_params[:cells_service_name]).without_ensure }
|
||||
end
|
||||
|
||||
shared_examples_for 'a child cell' do
|
||||
@ -131,8 +133,9 @@ describe 'nova::cells' do
|
||||
let :expected_params do
|
||||
default_params.merge(params)
|
||||
end
|
||||
it { should contain_nova_config('cells/name').with_value(expected_params[:cell_name]) }
|
||||
it { should contain_nova_config('DEFAULT/quota_driver').with_value('nova.quota.NoopQuotaDriver')}
|
||||
it { is_expected.to contain_nova_config('cells/name').with_value(expected_params[:cell_name]) }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/quota_driver').with_value('nova.quota.NoopQuotaDriver')}
|
||||
it { is_expected.to contain_nova_config('cells/cell_type').with_value('compute')}
|
||||
it_configures 'nova-cells'
|
||||
end
|
||||
|
||||
|
@ -3,13 +3,18 @@ require 'spec_helper'
|
||||
describe 'nova::client' do
|
||||
|
||||
context 'with default parameters' do
|
||||
it { should contain_package('python-novaclient').with_ensure('present') }
|
||||
it {
|
||||
is_expected.to contain_package('python-novaclient').with(
|
||||
:ensure => 'present',
|
||||
:tag => ['openstack']
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
context 'with ensure parameter provided' do
|
||||
let :params do
|
||||
{ :ensure => '2012.1-2' }
|
||||
end
|
||||
it { should contain_package('python-novaclient').with_ensure('2012.1-2') }
|
||||
it { is_expected.to contain_package('python-novaclient').with_ensure('2012.1-2') }
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
describe 'nova::compute::ironic' do
|
||||
|
||||
it 'configures ironic in nova.conf' do
|
||||
is_expected.to contain_nova_config('ironic/admin_username').with_value('admin')
|
||||
is_expected.to contain_nova_config('ironic/admin_password').with_value('ironic')
|
||||
is_expected.to contain_nova_config('ironic/admin_url').with_value('http://127.0.0.1:35357/v2.0')
|
||||
is_expected.to contain_nova_config('ironic/admin_tenant_name').with_value('services')
|
||||
is_expected.to contain_nova_config('ironic/api_endpoint').with_value('http://127.0.0.1:6385/v1')
|
||||
is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('nova.virt.ironic.IronicDriver')
|
||||
end
|
||||
|
||||
end
|
@ -12,36 +12,40 @@ describe 'nova::compute::libvirt' do
|
||||
|
||||
describe 'with default parameters' do
|
||||
|
||||
it { should contain_class('nova::params')}
|
||||
it { is_expected.to contain_class('nova::params')}
|
||||
|
||||
it { should contain_package('nova-compute-kvm').with(
|
||||
it { is_expected.to contain_package('nova-compute-kvm').with(
|
||||
:ensure => 'present',
|
||||
:before => 'Package[nova-compute]'
|
||||
:before => 'Package[nova-compute]',
|
||||
:tag => ['openstack']
|
||||
) }
|
||||
|
||||
it { should contain_package('libvirt').with(
|
||||
it { is_expected.to contain_package('libvirt').with(
|
||||
:name => 'libvirt-bin',
|
||||
:ensure => 'present'
|
||||
) }
|
||||
|
||||
it { should contain_service('libvirt').with(
|
||||
it { is_expected.to contain_service('libvirt').with(
|
||||
:name => 'libvirt-bin',
|
||||
:enable => true,
|
||||
:ensure => 'running',
|
||||
:provider => 'upstart',
|
||||
:require => 'Package[libvirt]',
|
||||
:before => 'Service[nova-compute]'
|
||||
:before => ['Service[nova-compute]']
|
||||
)}
|
||||
|
||||
it { should contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { should contain_nova_config('libvirt/cpu_mode').with_value('host-model')}
|
||||
it { should contain_nova_config('libvirt/disk_cachemodes').with_ensure('absent')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_base_images').with_ensure('absent')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_ensure('absent')}
|
||||
it { should contain_nova_config('libvirt/remove_unused_kernels').with_ensure('absent')}
|
||||
it { should contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { is_expected.to contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { is_expected.to contain_nova_config('libvirt/cpu_mode').with_value('host-model')}
|
||||
it { is_expected.to contain_nova_config('libvirt/disk_cachemodes').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_password').with_value(false)}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_key').with_value(false)}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_partition').with_value(-2)}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_base_images').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_kernels').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_ensure('absent')}
|
||||
end
|
||||
|
||||
describe 'with params' do
|
||||
@ -53,27 +57,26 @@ describe 'nova::compute::libvirt' do
|
||||
:remove_unused_base_images => true,
|
||||
:remove_unused_kernels => true,
|
||||
:remove_unused_resized_minimum_age_seconds => 3600,
|
||||
:remove_unused_original_minimum_age_seconds => 3600
|
||||
:remove_unused_original_minimum_age_seconds => 3600,
|
||||
:libvirt_service_name => 'custom_service'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { should contain_nova_config('libvirt/cpu_mode').with_value('host-passthrough')}
|
||||
it { should contain_nova_config('libvirt/disk_cachemodes').with_value('file=directsync,block=none')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_base_images').with_value(true)}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_value(3600)}
|
||||
it { should contain_nova_config('libvirt/remove_unused_kernels').with_value(true)}
|
||||
it { should contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_value(3600)}
|
||||
end
|
||||
|
||||
describe 'with deprecated params' do
|
||||
let :params do
|
||||
{ :libvirt_type => 'qemu'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { is_expected.to contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { is_expected.to contain_nova_config('libvirt/cpu_mode').with_value('host-passthrough')}
|
||||
it { is_expected.to contain_nova_config('libvirt/disk_cachemodes').with_value('file=directsync,block=none')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_base_images').with_value(true)}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_value(3600)}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_kernels').with_value(true)}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_value(3600)}
|
||||
it { is_expected.to contain_service('libvirt').with(
|
||||
:name => 'custom_service',
|
||||
:enable => true,
|
||||
:ensure => 'running',
|
||||
:require => 'Package[libvirt]',
|
||||
:before => ['Service[nova-compute]']
|
||||
)}
|
||||
end
|
||||
|
||||
describe 'with migration_support enabled' do
|
||||
@ -84,8 +87,20 @@ describe 'nova::compute::libvirt' do
|
||||
:migration_support => true }
|
||||
end
|
||||
|
||||
it { should contain_class('nova::migration::libvirt')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { is_expected.to contain_class('nova::migration::libvirt')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { is_expected.to contain_file_line('/etc/default/libvirt-bin libvirtd opts').with(:line => 'libvirtd_opts="-d -l"') }
|
||||
end
|
||||
|
||||
context 'with vncserver_listen set to ::0' do
|
||||
let :params do
|
||||
{ :vncserver_listen => '::0',
|
||||
:migration_support => true }
|
||||
end
|
||||
|
||||
it { is_expected.to contain_class('nova::migration::libvirt')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('::0')}
|
||||
it { is_expected.to contain_file_line('/etc/default/libvirt-bin libvirtd opts').with(:line => 'libvirtd_opts="-d -l"') }
|
||||
end
|
||||
|
||||
context 'with vncserver_listen not set to 0.0.0.0' do
|
||||
@ -94,8 +109,18 @@ describe 'nova::compute::libvirt' do
|
||||
:migration_support => true }
|
||||
end
|
||||
|
||||
it { expect { should contain_class('nova::compute::libvirt') }.to \
|
||||
raise_error(Puppet::Error, /For migration support to work, you MUST set vncserver_listen to '0.0.0.0'/) }
|
||||
it { expect { is_expected.to contain_class('nova::compute::libvirt') }.to \
|
||||
raise_error(Puppet::Error, /For migration support to work, you MUST set vncserver_listen to '0.0.0.0' or '::0'/) }
|
||||
end
|
||||
|
||||
context 'with custom libvirt service name on Debian platforms' do
|
||||
let :params do
|
||||
{ :libvirt_service_name => 'libvirtd',
|
||||
:vncserver_listen => '0.0.0.0',
|
||||
:migration_support => true }
|
||||
end
|
||||
it { is_expected.to contain_file_line('/etc/default/libvirtd libvirtd opts').with(:line => 'libvirtd_opts="-d -l"') }
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -104,54 +129,61 @@ describe 'nova::compute::libvirt' do
|
||||
describe 'on rhel platforms' do
|
||||
let :facts do
|
||||
{ :operatingsystem => 'RedHat', :osfamily => 'RedHat',
|
||||
:operatingsystemrelease => 6.5 }
|
||||
:operatingsystemrelease => 6.5,
|
||||
:operatingsystemmajrelease => '6' }
|
||||
end
|
||||
|
||||
describe 'with default parameters' do
|
||||
|
||||
it { should contain_class('nova::params')}
|
||||
it { is_expected.to contain_class('nova::params')}
|
||||
|
||||
it { should contain_package('libvirt').with(
|
||||
it { is_expected.to contain_package('libvirt').with(
|
||||
:name => 'libvirt',
|
||||
:ensure => 'present'
|
||||
) }
|
||||
|
||||
it { should contain_service('libvirt').with(
|
||||
it { is_expected.to contain_service('libvirt').with(
|
||||
:name => 'libvirtd',
|
||||
:enable => true,
|
||||
:ensure => 'running',
|
||||
:provider => nil,
|
||||
:provider => 'init',
|
||||
:require => 'Package[libvirt]',
|
||||
:before => 'Service[nova-compute]'
|
||||
:before => ['Service[nova-compute]']
|
||||
)}
|
||||
it { should contain_service('messagebus').with(
|
||||
it { is_expected.to contain_service('messagebus').with(
|
||||
:ensure => 'running',
|
||||
:enable => true,
|
||||
:before => 'Service[libvirt]',
|
||||
:provider => nil
|
||||
:before => ['Service[libvirt]'],
|
||||
:provider => 'init',
|
||||
:name => 'messagebus'
|
||||
) }
|
||||
|
||||
describe 'on rhel 7' do
|
||||
let :facts do
|
||||
super().merge(:operatingsystemrelease => 7.0)
|
||||
super().merge(:operatingsystemmajrelease => '7')
|
||||
end
|
||||
|
||||
it { should contain_service('libvirt').with(
|
||||
it { is_expected.to contain_service('libvirt').with(
|
||||
:provider => nil
|
||||
)}
|
||||
|
||||
it { should contain_service('messagebus').with(
|
||||
:provider => nil
|
||||
it { is_expected.to contain_service('messagebus').with(
|
||||
:provider => nil,
|
||||
:name => 'dbus'
|
||||
)}
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_base_images').with_ensure('absent')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_ensure('absent')}
|
||||
it { should contain_nova_config('libvirt/remove_unused_kernels').with_ensure('absent')}
|
||||
it { should contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { is_expected.to contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_password').with_value(false)}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_key').with_value(false)}
|
||||
it { is_expected.to contain_nova_config('libvirt/inject_partition').with_value(-2)}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_base_images').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_kernels').with_ensure('absent')}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_ensure('absent')}
|
||||
end
|
||||
|
||||
describe 'with params' do
|
||||
@ -165,21 +197,12 @@ describe 'nova::compute::libvirt' do
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_base_images').with_value(true)}
|
||||
it { should contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_value(3600)}
|
||||
it { should contain_nova_config('libvirt/remove_unused_kernels').with_value(true)}
|
||||
it { should contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_value(3600)}
|
||||
end
|
||||
|
||||
describe 'with deprecated params' do
|
||||
let :params do
|
||||
{ :libvirt_type => 'qemu'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { is_expected.to contain_nova_config('libvirt/virt_type').with_value('qemu')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_base_images').with_value(true)}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/remove_unused_original_minimum_age_seconds').with_value(3600)}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_kernels').with_value(true)}
|
||||
it { is_expected.to contain_nova_config('libvirt/remove_unused_resized_minimum_age_seconds').with_value(3600)}
|
||||
end
|
||||
|
||||
describe 'with migration_support enabled' do
|
||||
@ -190,8 +213,8 @@ describe 'nova::compute::libvirt' do
|
||||
:migration_support => true }
|
||||
end
|
||||
|
||||
it { should contain_class('nova::migration::libvirt')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
it { is_expected.to contain_class('nova::migration::libvirt')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('0.0.0.0')}
|
||||
end
|
||||
|
||||
context 'with vncserver_listen not set to 0.0.0.0' do
|
||||
@ -200,7 +223,7 @@ describe 'nova::compute::libvirt' do
|
||||
:migration_support => true }
|
||||
end
|
||||
|
||||
it { expect { should contain_class('nova::compute::libvirt') }.to \
|
||||
it { expect { is_expected.to contain_class('nova::compute::libvirt') }.to \
|
||||
raise_error(Puppet::Error, /For migration support to work, you MUST set vncserver_listen to '0.0.0.0'/) }
|
||||
end
|
||||
end
|
||||
@ -210,25 +233,25 @@ describe 'nova::compute::libvirt' do
|
||||
{ :operatingsystem => 'Fedora', :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it { should contain_class('nova::params')}
|
||||
it { is_expected.to contain_class('nova::params')}
|
||||
|
||||
it { should contain_package('libvirt').with(
|
||||
it { is_expected.to contain_package('libvirt').with(
|
||||
:name => 'libvirt',
|
||||
:ensure => 'present'
|
||||
) }
|
||||
|
||||
it { should contain_service('libvirt').with(
|
||||
it { is_expected.to contain_service('libvirt').with(
|
||||
:name => 'libvirtd',
|
||||
:enable => true,
|
||||
:ensure => 'running',
|
||||
:provider => nil,
|
||||
:require => 'Package[libvirt]',
|
||||
:before => 'Service[nova-compute]'
|
||||
:before => ['Service[nova-compute]']
|
||||
)}
|
||||
|
||||
it { should contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { should contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { should contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('libvirt.LibvirtDriver')}
|
||||
it { is_expected.to contain_nova_config('libvirt/virt_type').with_value('kvm')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vncserver_listen').with_value('127.0.0.1')}
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,22 +1,56 @@
|
||||
require 'spec_helper'
|
||||
describe 'nova::compute::neutron' do
|
||||
|
||||
it { should contain_nova_config('libvirt/vif_driver').with_value('nova.virt.libvirt.vif.LibvirtGenericVIFDriver')}
|
||||
context 'with default parameters' do
|
||||
it { is_expected.to contain_nova_config('libvirt/vif_driver').with_value('nova.virt.libvirt.vif.LibvirtGenericVIFDriver')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_snat_range').with(:value => '0.0.0.0/0') }
|
||||
end
|
||||
|
||||
context 'when overriding params' do
|
||||
let :params do
|
||||
{:libvirt_vif_driver => 'foo' }
|
||||
end
|
||||
it { should contain_nova_config('libvirt/vif_driver').with_value('foo')}
|
||||
it { is_expected.to contain_nova_config('libvirt/vif_driver').with_value('foo')}
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_snat_range').with_ensure(:absent) }
|
||||
end
|
||||
|
||||
context 'when overriding with a removed libvirt_vif_driver param' do
|
||||
let :params do
|
||||
{:libvirt_vif_driver => 'nova.virt.libvirt.vif.LibvirtOpenVswitchDriver' }
|
||||
end
|
||||
it 'should fails to configure libvirt_vif_driver with old OVS driver' do
|
||||
expect { subject }.to raise_error(Puppet::Error, /nova.virt.libvirt.vif.LibvirtOpenVswitchDriver as vif_driver is removed from Icehouse/)
|
||||
|
||||
it_raises 'a Puppet::Error', /nova.virt.libvirt.vif.LibvirtOpenVswitchDriver as vif_driver is removed from Icehouse/
|
||||
end
|
||||
|
||||
context 'with force_snat_range parameter set to false' do
|
||||
let :params do
|
||||
{ :force_snat_range => false, }
|
||||
end
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_snat_range').with_ensure('absent') }
|
||||
end
|
||||
|
||||
context 'with force_snat_range parameter set to 10.0.0.0/24' do
|
||||
let :params do
|
||||
{ :force_snat_range => '10.0.0.0/24', }
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_snat_range').with_value('10.0.0.0/24') }
|
||||
end
|
||||
|
||||
context 'with force_snat_range parameter set to fe80::/64' do
|
||||
let :params do
|
||||
{ :force_snat_range => 'fe80::/64', }
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_snat_range').with_value('fe80::/64') }
|
||||
end
|
||||
|
||||
context 'with force_snat_range parameter set ip without mask' do
|
||||
let :params do
|
||||
{ :force_snat_range => '10.0.0.0', }
|
||||
end
|
||||
|
||||
it_raises 'a Puppet::Error', /force_snat_range should be IPv4 or IPv6 CIDR notation/
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -31,13 +31,13 @@ describe 'nova::compute::rbd' do
|
||||
|
||||
shared_examples_for 'nova compute rbd' do
|
||||
|
||||
it { should contain_class('nova::params') }
|
||||
it { is_expected.to contain_class('nova::params') }
|
||||
|
||||
it 'configure nova.conf with default parameters' do
|
||||
should contain_nova_config('libvirt/images_type').with_value('rbd')
|
||||
should contain_nova_config('libvirt/images_rbd_pool').with_value('rbd')
|
||||
should contain_nova_config('libvirt/images_rbd_ceph_conf').with_value('/etc/ceph/ceph.conf')
|
||||
should contain_nova_config('libvirt/rbd_user').with_value('nova')
|
||||
is_expected.to contain_nova_config('libvirt/images_type').with_value('rbd')
|
||||
is_expected.to contain_nova_config('libvirt/images_rbd_pool').with_value('rbd')
|
||||
is_expected.to contain_nova_config('libvirt/images_rbd_ceph_conf').with_value('/etc/ceph/ceph.conf')
|
||||
is_expected.to contain_nova_config('libvirt/rbd_user').with_value('nova')
|
||||
end
|
||||
|
||||
context 'when overriding default parameters' do
|
||||
@ -50,41 +50,57 @@ describe 'nova::compute::rbd' do
|
||||
)
|
||||
end
|
||||
|
||||
it 'configure nova.conf with overriden parameters' do
|
||||
should contain_nova_config('libvirt/images_type').with_value('rbd')
|
||||
should contain_nova_config('libvirt/images_rbd_pool').with_value('AnotherPool')
|
||||
should contain_nova_config('libvirt/images_rbd_ceph_conf').with_value('/tmp/ceph.conf')
|
||||
should contain_nova_config('libvirt/rbd_user').with_value('joe')
|
||||
it 'configure nova.conf with overridden parameters' do
|
||||
is_expected.to contain_nova_config('libvirt/images_type').with_value('rbd')
|
||||
is_expected.to contain_nova_config('libvirt/images_rbd_pool').with_value('AnotherPool')
|
||||
is_expected.to contain_nova_config('libvirt/images_rbd_ceph_conf').with_value('/tmp/ceph.conf')
|
||||
is_expected.to contain_nova_config('libvirt/rbd_user').with_value('joe')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using cephx' do
|
||||
before :each do
|
||||
params.merge!(
|
||||
:libvirt_rbd_secret_uuid => 'UUID'
|
||||
:libvirt_rbd_secret_uuid => 'UUID',
|
||||
:rbd_keyring => 'client.rbd_test'
|
||||
)
|
||||
end
|
||||
|
||||
it 'configure nova.conf with RBD secret UUID' do
|
||||
should contain_nova_config('libvirt/rbd_secret_uuid').with_value('UUID')
|
||||
is_expected.to contain_nova_config('libvirt/rbd_secret_uuid').with_value('UUID')
|
||||
end
|
||||
|
||||
it 'configure ceph on compute nodes' do
|
||||
verify_contents(subject, '/etc/nova/secret.xml', [
|
||||
verify_contents(catalogue, '/etc/nova/secret.xml', [
|
||||
"<secret ephemeral=\'no\' private=\'no\'>",
|
||||
" <usage type=\'ceph\'>",
|
||||
" <name>client.nova secret</name>",
|
||||
" <name>client.rbd_test secret</name>",
|
||||
" </usage>",
|
||||
" <uuid>UUID</uuid>",
|
||||
"</secret>"
|
||||
])
|
||||
should contain_exec('get-or-set virsh secret').with(
|
||||
is_expected.to contain_exec('get-or-set virsh secret').with(
|
||||
:command => '/usr/bin/virsh secret-define --file /etc/nova/secret.xml | /usr/bin/awk \'{print $2}\' | sed \'/^$/d\' > /etc/nova/virsh.secret',
|
||||
:creates => '/etc/nova/virsh.secret',
|
||||
:require => 'File[/etc/nova/secret.xml]'
|
||||
)
|
||||
should contain_exec('set-secret-value virsh').with(
|
||||
:command => "/usr/bin/virsh secret-set-value --secret $(cat /etc/nova/virsh.secret) --base64 $(ceph auth get-key client.nova)"
|
||||
is_expected.to contain_exec('set-secret-value virsh').with(
|
||||
:command => "/usr/bin/virsh secret-set-value --secret UUID --base64 $(ceph auth get-key client.rbd_test)"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using cephx and passing libvirt_rbd_secret_key' do
|
||||
before :each do
|
||||
params.merge!(
|
||||
:libvirt_rbd_secret_uuid => 'UUID',
|
||||
:libvirt_rbd_secret_key => 'LIBVIRT/SECRET/KEY',
|
||||
)
|
||||
end
|
||||
|
||||
it 'set libvirt secret key from passed key' do
|
||||
is_expected.to contain_exec('set-secret-value virsh').with(
|
||||
:command => "/usr/bin/virsh secret-set-value --secret #{params[:libvirt_rbd_secret_uuid]} --base64 #{params[:libvirt_rbd_secret_key]}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,21 @@
|
||||
require 'spec_helper'
|
||||
describe 'nova::compute::serial' do
|
||||
|
||||
it { is_expected.to contain_nova_config('serial_console/enabled').with_value('true') }
|
||||
it { is_expected.to contain_nova_config('serial_console/port_range').with_value('10000:20000')}
|
||||
it { is_expected.to contain_nova_config('serial_console/base_url').with_value('ws://127.0.0.1:6083/')}
|
||||
it { is_expected.to contain_nova_config('serial_console/listen').with_value('127.0.0.1')}
|
||||
it { is_expected.to contain_nova_config('serial_console/proxyclient_address').with_value('127.0.0.1')}
|
||||
|
||||
context 'when overriding params' do
|
||||
let :params do
|
||||
{
|
||||
:proxyclient_address => '10.10.10.10',
|
||||
:listen => '10.10.11.11',
|
||||
}
|
||||
end
|
||||
it { is_expected.to contain_nova_config('serial_console/proxyclient_address').with_value('10.10.10.10')}
|
||||
it { is_expected.to contain_nova_config('serial_console/listen').with_value('10.10.11.11')}
|
||||
end
|
||||
|
||||
end
|
@ -11,28 +11,38 @@ describe 'nova::compute' do
|
||||
context 'with default parameters' do
|
||||
|
||||
it 'installs nova-compute package and service' do
|
||||
should contain_service('nova-compute').with({
|
||||
is_expected.to contain_service('nova-compute').with({
|
||||
:name => platform_params[:nova_compute_service],
|
||||
:ensure => 'stopped',
|
||||
:hasstatus => true,
|
||||
:enable => false
|
||||
})
|
||||
should contain_package('nova-compute').with({
|
||||
:name => platform_params[:nova_compute_package]
|
||||
is_expected.to contain_package('nova-compute').with({
|
||||
:name => platform_params[:nova_compute_package],
|
||||
:tag => ['openstack']
|
||||
})
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/network_device_mtu').with(:ensure => 'absent') }
|
||||
it { should_not contain_nova_config('DEFAULT/novncproxy_base_url') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/network_device_mtu').with(:ensure => 'absent') }
|
||||
it { is_expected.to_not contain_nova_config('DEFAULT/novncproxy_base_url') }
|
||||
|
||||
it { should_not contain_package('bridge-utils').with(
|
||||
it { is_expected.to_not contain_package('bridge-utils').with(
|
||||
:ensure => 'present',
|
||||
:before => 'Nova::Generic_service[compute]'
|
||||
) }
|
||||
|
||||
it { should contain_package('pm-utils').with(
|
||||
it { is_expected.to contain_package('pm-utils').with(
|
||||
:ensure => 'present'
|
||||
) }
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_raw_images').with(:value => true) }
|
||||
|
||||
it 'configures availability zones' do
|
||||
is_expected.to contain_nova_config('DEFAULT/default_availability_zone').with_value('nova')
|
||||
is_expected.to contain_nova_config('DEFAULT/internal_service_availability_zone').with_value('internal')
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/heal_instance_info_cache_interval').with_value('60') }
|
||||
end
|
||||
|
||||
context 'with overridden parameters' do
|
||||
@ -41,41 +51,62 @@ describe 'nova::compute' do
|
||||
:ensure_package => '2012.1-2',
|
||||
:vncproxy_host => '127.0.0.1',
|
||||
:network_device_mtu => 9999,
|
||||
:force_raw_images => false,
|
||||
:reserved_host_memory => '0',
|
||||
:compute_manager => 'ironic.nova.compute.manager.ClusteredComputeManager',
|
||||
:default_availability_zone => 'az1',
|
||||
:default_schedule_zone => 'az2',
|
||||
:internal_service_availability_zone => 'az_int1',
|
||||
:heal_instance_info_cache_interval => '120',
|
||||
:pci_passthrough => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"physical_network\":\"physnet1\"}]"
|
||||
}
|
||||
end
|
||||
|
||||
it 'installs nova-compute package and service' do
|
||||
should contain_service('nova-compute').with({
|
||||
is_expected.to contain_service('nova-compute').with({
|
||||
:name => platform_params[:nova_compute_service],
|
||||
:ensure => 'running',
|
||||
:hasstatus => true,
|
||||
:enable => true
|
||||
})
|
||||
should contain_package('nova-compute').with({
|
||||
is_expected.to contain_package('nova-compute').with({
|
||||
:name => platform_params[:nova_compute_package],
|
||||
:ensure => '2012.1-2'
|
||||
:ensure => '2012.1-2',
|
||||
:tag => ['openstack']
|
||||
})
|
||||
end
|
||||
|
||||
it 'configures ironic in nova.conf' do
|
||||
is_expected.to contain_nova_config('DEFAULT/reserved_host_memory_mb').with_value('0')
|
||||
is_expected.to contain_nova_config('DEFAULT/compute_manager').with_value('ironic.nova.compute.manager.ClusteredComputeManager')
|
||||
end
|
||||
|
||||
it 'configures network_device_mtu' do
|
||||
should contain_nova_config('DEFAULT/network_device_mtu').with_value('9999')
|
||||
is_expected.to contain_nova_config('DEFAULT/network_device_mtu').with_value('9999')
|
||||
end
|
||||
|
||||
it 'configures vnc in nova.conf' do
|
||||
should contain_nova_config('DEFAULT/vnc_enabled').with_value(true)
|
||||
should contain_nova_config('DEFAULT/vncserver_proxyclient_address').with_value('127.0.0.1')
|
||||
should contain_nova_config('DEFAULT/novncproxy_base_url').with_value(
|
||||
is_expected.to contain_nova_config('DEFAULT/vnc_enabled').with_value(true)
|
||||
is_expected.to contain_nova_config('DEFAULT/vncserver_proxyclient_address').with_value('127.0.0.1')
|
||||
is_expected.to contain_nova_config('DEFAULT/novncproxy_base_url').with_value(
|
||||
'http://127.0.0.1:6080/vnc_auto.html'
|
||||
)
|
||||
end
|
||||
|
||||
it 'configures availability zones' do
|
||||
should contain_nova_config('DEFAULT/default_availability_zone').with_value('az1')
|
||||
should contain_nova_config('DEFAULT/default_schedule_zone').with_value('az2')
|
||||
should contain_nova_config('DEFAULT/internal_service_availability_zone').with_value('az_int1')
|
||||
is_expected.to contain_nova_config('DEFAULT/default_availability_zone').with_value('az1')
|
||||
is_expected.to contain_nova_config('DEFAULT/default_schedule_zone').with_value('az2')
|
||||
is_expected.to contain_nova_config('DEFAULT/internal_service_availability_zone').with_value('az_int1')
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/heal_instance_info_cache_interval').with_value('120') }
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_raw_images').with(:value => false) }
|
||||
|
||||
it 'configures nova pci_passthrough_whitelist entries' do
|
||||
is_expected.to contain_nova_config('DEFAULT/pci_passthrough_whitelist').with(
|
||||
'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"physical_network\":\"physnet1\"}]"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -85,7 +116,7 @@ describe 'nova::compute' do
|
||||
end
|
||||
|
||||
it 'installs bridge-utils package for nova-network' do
|
||||
should contain_package('bridge-utils').with(
|
||||
is_expected.to contain_package('bridge-utils').with(
|
||||
:ensure => 'present',
|
||||
:before => 'Nova::Generic_service[compute]'
|
||||
)
|
||||
@ -98,9 +129,9 @@ describe 'nova::compute' do
|
||||
end
|
||||
|
||||
it 'disables vnc in nova.conf' do
|
||||
should contain_nova_config('DEFAULT/vnc_enabled').with_value(false)
|
||||
should contain_nova_config('DEFAULT/vncserver_proxyclient_address').with_value('127.0.0.1')
|
||||
should_not contain_nova_config('DEFAULT/novncproxy_base_url')
|
||||
is_expected.to contain_nova_config('DEFAULT/vnc_enabled').with_value(false)
|
||||
is_expected.to contain_nova_config('DEFAULT/vncserver_proxyclient_address').with_value('127.0.0.1')
|
||||
is_expected.to_not contain_nova_config('DEFAULT/novncproxy_base_url')
|
||||
end
|
||||
end
|
||||
|
||||
@ -109,7 +140,7 @@ describe 'nova::compute' do
|
||||
{ :force_config_drive => true }
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/force_config_drive').with_value(true) }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/force_config_drive').with_value(true) }
|
||||
end
|
||||
|
||||
context 'while not managing service state' do
|
||||
@ -119,7 +150,7 @@ describe 'nova::compute' do
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_service('nova-compute').without_ensure }
|
||||
it { is_expected.to contain_service('nova-compute').without_ensure }
|
||||
end
|
||||
|
||||
context 'with instance_usage_audit parameter set to false' do
|
||||
@ -127,8 +158,8 @@ describe 'nova::compute' do
|
||||
{ :instance_usage_audit => false, }
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit').with_ensure('absent') }
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit_period').with_ensure('absent') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit').with_ensure('absent') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit_period').with_ensure('absent') }
|
||||
end
|
||||
|
||||
context 'with instance_usage_audit parameter and wrong period' do
|
||||
@ -137,8 +168,8 @@ describe 'nova::compute' do
|
||||
:instance_usage_audit_period => 'fake', }
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit').with_ensure('absent') }
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit_period').with_ensure('absent') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit').with_ensure('absent') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit_period').with_ensure('absent') }
|
||||
end
|
||||
|
||||
context 'with instance_usage_audit parameter and period' do
|
||||
@ -147,8 +178,15 @@ describe 'nova::compute' do
|
||||
:instance_usage_audit_period => 'year', }
|
||||
end
|
||||
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit').with_value(true) }
|
||||
it { should contain_nova_config('DEFAULT/instance_usage_audit_period').with_value('year') }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit').with_value(true) }
|
||||
it { is_expected.to contain_nova_config('DEFAULT/instance_usage_audit_period').with_value('year') }
|
||||
end
|
||||
context 'with vnc_keymap set to fr' do
|
||||
let :params do
|
||||
{ :vnc_keymap => 'fr', }
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('DEFAULT/vnc_keymap').with_value('fr') }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
require 'spec_helper'
|
||||
describe 'nova::compute::spice' do
|
||||
|
||||
it { should contain_nova_config('spice/enabled').with_value('true')}
|
||||
it { should contain_nova_config('spice/agent_enabled').with_value('true')}
|
||||
it { should contain_nova_config('spice/server_proxyclient_address').with_value('127.0.0.1')}
|
||||
it { should_not contain_nova_config('spice/html5proxy_base_url')}
|
||||
it { should contain_nova_config('spice/server_listen').with_value(nil)}
|
||||
it { is_expected.to contain_nova_config('spice/enabled').with_value('true')}
|
||||
it { is_expected.to contain_nova_config('spice/agent_enabled').with_value('true')}
|
||||
it { is_expected.to contain_nova_config('spice/server_proxyclient_address').with_value('127.0.0.1')}
|
||||
it { is_expected.to_not contain_nova_config('spice/html5proxy_base_url')}
|
||||
it { is_expected.to contain_nova_config('spice/server_listen').with_value(nil)}
|
||||
|
||||
context 'when overriding params' do
|
||||
let :params do
|
||||
@ -15,9 +15,9 @@ describe 'nova::compute::spice' do
|
||||
:agent_enabled => false
|
||||
}
|
||||
end
|
||||
it { should contain_nova_config('spice/html5proxy_base_url').with_value('http://10.10.10.10:6082/spice_auto.html')}
|
||||
it { should contain_nova_config('spice/server_listen').with_value('10.10.11.11')}
|
||||
it { should contain_nova_config('spice/agent_enabled').with_value('false')}
|
||||
it { is_expected.to contain_nova_config('spice/html5proxy_base_url').with_value('http://10.10.10.10:6082/spice_auto.html')}
|
||||
it { is_expected.to contain_nova_config('spice/server_listen').with_value('10.10.11.11')}
|
||||
it { is_expected.to contain_nova_config('spice/agent_enabled').with_value('false')}
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -18,20 +18,20 @@ describe 'nova::compute::vmware' do
|
||||
end
|
||||
|
||||
it 'configures vmwareapi in nova.conf' do
|
||||
should contain_nova_config('DEFAULT/compute_driver').with_value('vmwareapi.VMwareVCDriver')
|
||||
should contain_nova_config('VMWARE/host_ip').with_value(params[:host_ip])
|
||||
should contain_nova_config('VMWARE/host_username').with_value(params[:host_username])
|
||||
should contain_nova_config('VMWARE/host_password').with_value(params[:host_password])
|
||||
should contain_nova_config('VMWARE/cluster_name').with_value(params[:cluster_name])
|
||||
should contain_nova_config('VMWARE/api_retry_count').with_value(5)
|
||||
should contain_nova_config('VMWARE/maximum_objects').with_value(100)
|
||||
should contain_nova_config('VMWARE/task_poll_interval').with_value(5.0)
|
||||
should contain_nova_config('VMWARE/use_linked_clone').with_value(true)
|
||||
should_not contain_nova_config('VMWARE/wsdl_location')
|
||||
is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('vmwareapi.VMwareVCDriver')
|
||||
is_expected.to contain_nova_config('VMWARE/host_ip').with_value(params[:host_ip])
|
||||
is_expected.to contain_nova_config('VMWARE/host_username').with_value(params[:host_username])
|
||||
is_expected.to contain_nova_config('VMWARE/host_password').with_value(params[:host_password])
|
||||
is_expected.to contain_nova_config('VMWARE/cluster_name').with_value(params[:cluster_name])
|
||||
is_expected.to contain_nova_config('VMWARE/api_retry_count').with_value(5)
|
||||
is_expected.to contain_nova_config('VMWARE/maximum_objects').with_value(100)
|
||||
is_expected.to contain_nova_config('VMWARE/task_poll_interval').with_value(5.0)
|
||||
is_expected.to contain_nova_config('VMWARE/use_linked_clone').with_value(true)
|
||||
is_expected.to_not contain_nova_config('VMWARE/wsdl_location')
|
||||
end
|
||||
|
||||
it 'installs suds python package' do
|
||||
should contain_package('python-suds').with(
|
||||
is_expected.to contain_package('python-suds').with(
|
||||
:ensure => 'present'
|
||||
)
|
||||
end
|
||||
@ -42,11 +42,11 @@ describe 'nova::compute::vmware' do
|
||||
end
|
||||
|
||||
it 'configures vmwareapi in nova.conf' do
|
||||
should contain_nova_config('VMWARE/api_retry_count').with_value(params[:api_retry_count])
|
||||
should contain_nova_config('VMWARE/maximum_objects').with_value(params[:maximum_objects])
|
||||
should contain_nova_config('VMWARE/task_poll_interval').with_value(params[:task_poll_interval])
|
||||
should contain_nova_config('VMWARE/use_linked_clone').with_value(false)
|
||||
should contain_nova_config('VMWARE/wsdl_location').with_value(params[:wsdl_location])
|
||||
is_expected.to contain_nova_config('VMWARE/api_retry_count').with_value(params[:api_retry_count])
|
||||
is_expected.to contain_nova_config('VMWARE/maximum_objects').with_value(params[:maximum_objects])
|
||||
is_expected.to contain_nova_config('VMWARE/task_poll_interval').with_value(params[:task_poll_interval])
|
||||
is_expected.to contain_nova_config('VMWARE/use_linked_clone').with_value(false)
|
||||
is_expected.to contain_nova_config('VMWARE/wsdl_location').with_value(params[:wsdl_location])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,16 +11,16 @@ describe 'nova::compute::xenserver' do
|
||||
context 'with required parameters' do
|
||||
|
||||
it 'configures xenapi in nova.conf' do
|
||||
should contain_nova_config('DEFAULT/compute_driver').with_value('xenapi.XenAPIDriver')
|
||||
should contain_nova_config('DEFAULT/connection_type').with_value('xenapi')
|
||||
should contain_nova_config('DEFAULT/xenapi_connection_url').with_value(params[:xenapi_connection_url])
|
||||
should contain_nova_config('DEFAULT/xenapi_connection_username').with_value(params[:xenapi_connection_username])
|
||||
should contain_nova_config('DEFAULT/xenapi_connection_password').with_value(params[:xenapi_connection_password])
|
||||
should contain_nova_config('DEFAULT/xenapi_inject_image').with_value(false)
|
||||
is_expected.to contain_nova_config('DEFAULT/compute_driver').with_value('xenapi.XenAPIDriver')
|
||||
is_expected.to contain_nova_config('DEFAULT/connection_type').with_value('xenapi')
|
||||
is_expected.to contain_nova_config('DEFAULT/xenapi_connection_url').with_value(params[:xenapi_connection_url])
|
||||
is_expected.to contain_nova_config('DEFAULT/xenapi_connection_username').with_value(params[:xenapi_connection_username])
|
||||
is_expected.to contain_nova_config('DEFAULT/xenapi_connection_password').with_value(params[:xenapi_connection_password])
|
||||
is_expected.to contain_nova_config('DEFAULT/xenapi_inject_image').with_value(false)
|
||||
end
|
||||
|
||||
it 'installs xenapi with pip' do
|
||||
should contain_package('xenapi').with(
|
||||
is_expected.to contain_package('xenapi').with(
|
||||
:ensure => 'present',
|
||||
:provider => 'pip'
|
||||
)
|
||||
|
@ -6,25 +6,101 @@ describe 'nova::conductor' do
|
||||
'include nova'
|
||||
end
|
||||
|
||||
let :params do
|
||||
{ :enabled => true }
|
||||
end
|
||||
|
||||
shared_examples 'nova-conductor' do
|
||||
|
||||
|
||||
it { is_expected.to contain_package('nova-conductor').with(
|
||||
:name => platform_params[:conductor_package_name],
|
||||
:ensure => 'present'
|
||||
) }
|
||||
|
||||
it { is_expected.to contain_service('nova-conductor').with(
|
||||
:name => platform_params[:conductor_service_name],
|
||||
:hasstatus => 'true',
|
||||
:ensure => 'running'
|
||||
)}
|
||||
|
||||
context 'with manage_service as false' do
|
||||
let :params do
|
||||
{ :enabled => true,
|
||||
:manage_service => false
|
||||
}
|
||||
end
|
||||
it { is_expected.to contain_service('nova-conductor').without_ensure }
|
||||
end
|
||||
|
||||
context 'with package version' do
|
||||
let :params do
|
||||
{ :ensure_package => '2012.1-2' }
|
||||
end
|
||||
|
||||
it { is_expected.to contain_package('nova-conductor').with(
|
||||
:ensure => params[:ensure_package]
|
||||
)}
|
||||
end
|
||||
|
||||
context 'with overriden workers parameter' do
|
||||
before do
|
||||
params.merge!({:workers => '5' })
|
||||
end
|
||||
it { is_expected.to contain_nova_config('conductor/workers').with_value('5') }
|
||||
end
|
||||
|
||||
context 'with default database parameters' do
|
||||
let :pre_condition do
|
||||
"include nova"
|
||||
end
|
||||
|
||||
it { is_expected.to_not contain_nova_config('database/connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/slave_connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/idle_timeout').with_value('3600') }
|
||||
end
|
||||
|
||||
context 'with overridden database parameters' do
|
||||
let :pre_condition do
|
||||
"class { 'nova':
|
||||
database_connection => 'mysql://user:pass@db/db',
|
||||
slave_connection => 'mysql://user:pass@slave/db',
|
||||
database_idle_timeout => '30',
|
||||
}
|
||||
"
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('database/connection').with_value('mysql://user:pass@db/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql://user:pass@slave/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/idle_timeout').with_value('30') }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it_behaves_like 'generic nova service', {
|
||||
:name => 'nova-conductor',
|
||||
:package_name => 'nova-conductor',
|
||||
:service_name => 'nova-conductor' }
|
||||
let :platform_params do
|
||||
{ :conductor_package_name => 'nova-conductor',
|
||||
:conductor_service_name => 'nova-conductor' }
|
||||
end
|
||||
|
||||
it_configures 'nova-conductor'
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
context 'on Redhat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it_behaves_like 'generic nova service', {
|
||||
:name => 'nova-conductor',
|
||||
:package_name => 'openstack-nova-conductor',
|
||||
:service_name => 'openstack-nova-conductor' }
|
||||
let :platform_params do
|
||||
{ :conductor_package_name => 'openstack-nova-conductor',
|
||||
:conductor_service_name => 'openstack-nova-conductor' }
|
||||
end
|
||||
|
||||
it_configures 'nova-conductor'
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -17,14 +17,14 @@ describe 'nova::config' do
|
||||
end
|
||||
|
||||
it 'configures arbitrary nova configurations' do
|
||||
should contain_nova_config('DEFAULT/foo').with_value('fooValue')
|
||||
should contain_nova_config('DEFAULT/bar').with_value('barValue')
|
||||
should contain_nova_config('DEFAULT/baz').with_ensure('absent')
|
||||
is_expected.to contain_nova_config('DEFAULT/foo').with_value('fooValue')
|
||||
is_expected.to contain_nova_config('DEFAULT/bar').with_value('barValue')
|
||||
is_expected.to contain_nova_config('DEFAULT/baz').with_ensure('absent')
|
||||
end
|
||||
|
||||
it 'configures arbitrary nova api-paste configurations' do
|
||||
should contain_nova_paste_api_ini('DEFAULT/foo2').with_value('fooValue')
|
||||
should contain_nova_paste_api_ini('DEFAULT/bar2').with_value('barValue')
|
||||
should contain_nova_paste_api_ini('DEFAULT/baz2').with_ensure('absent')
|
||||
is_expected.to contain_nova_paste_api_ini('DEFAULT/foo2').with_value('fooValue')
|
||||
is_expected.to contain_nova_paste_api_ini('DEFAULT/bar2').with_value('barValue')
|
||||
is_expected.to contain_nova_paste_api_ini('DEFAULT/baz2').with_ensure('absent')
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,22 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'nova::cron::archive_deleted_rows' do
|
||||
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it 'configures a cron' do
|
||||
is_expected.to contain_cron('nova-manage db archive_deleted_rows').with(
|
||||
:command => 'nova-manage db archive_deleted_rows --max_rows 100 >>/var/log/nova/nova-rowsflush.log 2>&1',
|
||||
:environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
:user => 'nova',
|
||||
:minute => 1,
|
||||
:hour => 0,
|
||||
:monthday => '*',
|
||||
:month => '*',
|
||||
:weekday => '*',
|
||||
:require => 'Package[nova-common]',
|
||||
)
|
||||
end
|
||||
end
|
@ -20,20 +20,20 @@ describe 'nova::db::mysql' do
|
||||
required_params
|
||||
end
|
||||
|
||||
it { should contain_mysql__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'qwerty',
|
||||
:charset => 'latin1',
|
||||
:require => "Class[Mysql::Config]"
|
||||
it { is_expected.to contain_openstacklib__db__mysql('nova').with(
|
||||
:user => 'nova',
|
||||
:password_hash => '*AA1420F182E88B9E5F874F6FBE7459291E8F4601',
|
||||
:charset => 'utf8',
|
||||
:collate => 'utf8_general_ci',
|
||||
)}
|
||||
end
|
||||
|
||||
context 'when overriding charset' do
|
||||
let :params do
|
||||
{ :charset => 'utf8' }.merge(required_params)
|
||||
{ :charset => 'latin1' }.merge(required_params)
|
||||
end
|
||||
|
||||
it { should contain_mysql__db('nova').with_charset(params[:charset]) }
|
||||
it { is_expected.to contain_openstacklib__db__mysql('nova').with_charset(params[:charset]) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -47,20 +47,20 @@ describe 'nova::db::mysql' do
|
||||
required_params
|
||||
end
|
||||
|
||||
it { should contain_mysql__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'qwerty',
|
||||
:charset => 'latin1',
|
||||
:require => "Class[Mysql::Config]"
|
||||
it { is_expected.to contain_openstacklib__db__mysql('nova').with(
|
||||
:user => 'nova',
|
||||
:password_hash => '*AA1420F182E88B9E5F874F6FBE7459291E8F4601',
|
||||
:charset => 'utf8',
|
||||
:collate => 'utf8_general_ci',
|
||||
)}
|
||||
end
|
||||
|
||||
context 'when overriding charset' do
|
||||
let :params do
|
||||
{ :charset => 'utf8' }.merge(required_params)
|
||||
{ :charset => 'latin1' }.merge(required_params)
|
||||
end
|
||||
|
||||
it { should contain_mysql__db('nova').with_charset(params[:charset]) }
|
||||
it { is_expected.to contain_openstacklib__db__mysql('nova').with_charset(params[:charset]) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -75,16 +75,6 @@ describe 'nova::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_nova__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'nova',
|
||||
:password => 'novapass',
|
||||
:database => 'nova'
|
||||
)}
|
||||
it {should contain_nova__db__mysql__host_access("%").with(
|
||||
:user => 'nova',
|
||||
:password => 'novapass',
|
||||
:database => 'nova'
|
||||
)}
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param to string" do
|
||||
@ -98,11 +88,6 @@ describe 'nova::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should contain_nova__db__mysql__host_access("192.168.1.1").with(
|
||||
:user => 'nova',
|
||||
:password => 'novapass2',
|
||||
:database => 'nova'
|
||||
)}
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param equals to host param " do
|
||||
@ -116,10 +101,5 @@ describe 'nova::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_nova__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'nova',
|
||||
:password => 'novapass2',
|
||||
:database => 'nova'
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
@ -1,26 +1,32 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'nova::db::postgresql' do
|
||||
let :required_params do
|
||||
{ :password => "qwerty" }
|
||||
|
||||
let :req_params do
|
||||
{ :password => 'pw' }
|
||||
end
|
||||
|
||||
let :pre_condition do
|
||||
'include postgresql::server'
|
||||
end
|
||||
|
||||
context 'on a RedHat osfamily' do
|
||||
let :facts do
|
||||
{
|
||||
:postgres_default_version => '8.4',
|
||||
:osfamily => 'RedHat'
|
||||
:osfamily => 'RedHat',
|
||||
:operatingsystemrelease => '7.0',
|
||||
:concat_basedir => '/var/lib/puppet/concat'
|
||||
}
|
||||
end
|
||||
|
||||
context 'with only required parameters' do
|
||||
let :params do
|
||||
required_params
|
||||
req_params
|
||||
end
|
||||
|
||||
it { should contain_postgresql__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'qwerty'
|
||||
it { is_expected.to contain_postgresql__server__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'md557ae0608fad632bf0155cb9502a6b454'
|
||||
)}
|
||||
end
|
||||
|
||||
@ -29,19 +35,21 @@ describe 'nova::db::postgresql' do
|
||||
context 'on a Debian osfamily' do
|
||||
let :facts do
|
||||
{
|
||||
:postgres_default_version => '8.4',
|
||||
:osfamily => 'Debian'
|
||||
:operatingsystemrelease => '7.8',
|
||||
:operatingsystem => 'Debian',
|
||||
:osfamily => 'Debian',
|
||||
:concat_basedir => '/var/lib/puppet/concat'
|
||||
}
|
||||
end
|
||||
|
||||
context 'with only required parameters' do
|
||||
let :params do
|
||||
required_params
|
||||
req_params
|
||||
end
|
||||
|
||||
it { should contain_postgresql__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'qwerty'
|
||||
it { is_expected.to contain_postgresql__server__db('nova').with(
|
||||
:user => 'nova',
|
||||
:password => 'md557ae0608fad632bf0155cb9502a6b454'
|
||||
)}
|
||||
end
|
||||
|
||||
|
49
deployment/puppet/nova/spec/classes/nova_db_spec.rb
Normal file
49
deployment/puppet/nova/spec/classes/nova_db_spec.rb
Normal file
@ -0,0 +1,49 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'nova::db' do
|
||||
|
||||
let :params do
|
||||
{}
|
||||
end
|
||||
|
||||
shared_examples 'nova-db' do
|
||||
|
||||
context 'with default parameters' do
|
||||
it { is_expected.to_not contain_nova_config('database/connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/slave_connection') }
|
||||
it { is_expected.to_not contain_nova_config('database/idle_timeout') }
|
||||
end
|
||||
|
||||
context 'with overriden parameters' do
|
||||
before :each do
|
||||
params.merge!(
|
||||
:database_connection => 'mysql://user:pass@db/db',
|
||||
:slave_connection => 'mysql://user:pass@slave/db',
|
||||
:database_idle_timeout => '30',
|
||||
)
|
||||
end
|
||||
|
||||
it { is_expected.to contain_nova_config('database/connection').with_value('mysql://user:pass@db/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql://user:pass@slave/db').with_secret(true) }
|
||||
it { is_expected.to contain_nova_config('database/idle_timeout').with_value('30') }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it_configures 'nova-db'
|
||||
end
|
||||
|
||||
context 'on Redhat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it_configures 'nova-db'
|
||||
end
|
||||
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user