First commit with basic manifests
Signed-off-by: Emilien Macchi <emilien.macchi@enovance.com>
This commit is contained in:
parent
0f0092dc0f
commit
e5b4e458ab
14
Gemfile
Normal file
14
Gemfile
Normal file
@ -0,0 +1,14 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
group :development, :test do
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
gem 'puppet-lint', '~> 0.3.2'
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
gem 'puppet', puppetversion, :require => false
|
||||
else
|
||||
gem 'puppet', :require => false
|
||||
end
|
||||
|
||||
# vim:ft=ruby
|
41
Gemfile.lock
Normal file
41
Gemfile.lock
Normal file
@ -0,0 +1,41 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
diff-lcs (1.2.4)
|
||||
facter (1.7.1)
|
||||
hiera (1.2.1)
|
||||
json_pure
|
||||
json_pure (1.8.0)
|
||||
metaclass (0.0.1)
|
||||
mocha (0.14.0)
|
||||
metaclass (~> 0.0.1)
|
||||
puppet (3.2.2)
|
||||
facter (~> 1.6)
|
||||
hiera (~> 1.0)
|
||||
rgen (~> 0.6)
|
||||
puppet-lint (0.3.2)
|
||||
puppetlabs_spec_helper (0.4.1)
|
||||
mocha (>= 0.10.5)
|
||||
rake
|
||||
rspec (>= 2.9.0)
|
||||
rspec-puppet (>= 0.1.1)
|
||||
rake (10.1.0)
|
||||
rgen (0.6.5)
|
||||
rspec (2.13.0)
|
||||
rspec-core (~> 2.13.0)
|
||||
rspec-expectations (~> 2.13.0)
|
||||
rspec-mocks (~> 2.13.0)
|
||||
rspec-core (2.13.1)
|
||||
rspec-expectations (2.13.0)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.13.1)
|
||||
rspec-puppet (0.1.6)
|
||||
rspec
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
puppet
|
||||
puppet-lint (~> 0.3.2)
|
||||
puppetlabs_spec_helper
|
30
LICENSE
30
LICENSE
@ -1,4 +1,5 @@
|
||||
Apache License
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
@ -173,30 +174,3 @@ Apache License
|
||||
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.
|
||||
|
||||
|
6
Rakefile
Normal file
6
Rakefile
Normal file
@ -0,0 +1,6 @@
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
require 'puppet-lint/tasks/puppet-lint'
|
||||
|
||||
PuppetLint.configuration.fail_on_warnings = true
|
||||
PuppetLint.configuration.send('disable_80chars')
|
||||
PuppetLint.configuration.send('disable_class_parameter_defaults')
|
150
lib/puppet/provider/ironic.rb
Normal file
150
lib/puppet/provider/ironic.rb
Normal file
@ -0,0 +1,150 @@
|
||||
require 'csv'
|
||||
require 'puppet/util/inifile'
|
||||
|
||||
class Puppet::Provider::Ironic < Puppet::Provider
|
||||
|
||||
def self.conf_filename
|
||||
'/etc/ironic/ironic.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.ironic_credentials
|
||||
@ironic_credentials ||= get_ironic_credentials
|
||||
end
|
||||
|
||||
def self.get_ironic_credentials
|
||||
auth_keys = ['auth_host', 'auth_port', 'auth_protocol',
|
||||
'admin_tenant_name', 'admin_user', 'admin_password']
|
||||
conf = ironic_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. Ironic types will not work if ironic is not \
|
||||
correctly configured.")
|
||||
end
|
||||
end
|
||||
|
||||
def ironic_credentials
|
||||
self.class.ironic_credentials
|
||||
end
|
||||
|
||||
def self.auth_endpoint
|
||||
@auth_endpoint ||= get_auth_endpoint
|
||||
end
|
||||
|
||||
def self.get_auth_endpoint
|
||||
q = ironic_credentials
|
||||
"#{q['auth_protocol']}://#{q['auth_host']}:#{q['auth_port']}/v2.0/"
|
||||
end
|
||||
|
||||
def self.ironic_conf
|
||||
return @ironic_conf if @ironic_conf
|
||||
@ironic_conf = Puppet::Util::IniConfig::File.new
|
||||
@ironic_conf.read(conf_filename)
|
||||
@ironic_conf
|
||||
end
|
||||
|
||||
def self.auth_ironic(*args)
|
||||
q = ironic_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
|
||||
ironic(args)
|
||||
end
|
||||
rescue Exception => e
|
||||
if (e.message =~ /\[Errno 111\] Connection refused/) or
|
||||
(e.message =~ /\(HTTP 400\)/)
|
||||
sleep 10
|
||||
withenv authenv do
|
||||
ironic(args)
|
||||
end
|
||||
else
|
||||
raise(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def auth_ironic(*args)
|
||||
self.class.auth_ironic(args)
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@ironic_conf = nil
|
||||
@ironic_credentials = nil
|
||||
end
|
||||
|
||||
def self.list_ironic_resources(type)
|
||||
ids = []
|
||||
list = auth_ironic("#{type}-list", '--format=csv',
|
||||
'--column=id', '--quote=none')
|
||||
(list.split("\n")[1..-1] || []).compact.collect do |line|
|
||||
ids << line.strip
|
||||
end
|
||||
return ids
|
||||
end
|
||||
|
||||
def self.get_ironic_resource_attrs(type, id)
|
||||
attrs = {}
|
||||
net = auth_ironic("#{type}-show", '--format=shell', id)
|
||||
last_key = nil
|
||||
(net.split("\n") || []).compact.collect do |line|
|
||||
if line.include? '='
|
||||
k, v = line.split('=', 2)
|
||||
attrs[k] = v.gsub(/\A"|"\Z/, '')
|
||||
last_key = k
|
||||
else
|
||||
# Handle the case of a list of values
|
||||
v = line.gsub(/\A"|"\Z/, '')
|
||||
attrs[last_key] = [attrs[last_key], v]
|
||||
end
|
||||
end
|
||||
return attrs
|
||||
end
|
||||
|
||||
def self.get_tenant_id(catalog, name)
|
||||
instance_type = 'keystone_tenant'
|
||||
instance = catalog.resource("#{instance_type.capitalize!}[#{name}]")
|
||||
if ! instance
|
||||
instance = Puppet::Type.type(instance_type).instances.find do |i|
|
||||
i.provider.name == name
|
||||
end
|
||||
end
|
||||
if instance
|
||||
return instance.provider.id
|
||||
else
|
||||
fail("Unable to find #{instance_type} for name #{name}")
|
||||
end
|
||||
end
|
||||
|
||||
def self.parse_creation_output(data)
|
||||
hash = {}
|
||||
data.split("\n").compact.each do |line|
|
||||
if line.include? '='
|
||||
hash[line.split('=').first] = line.split('=', 2)[1].gsub(/\A"|"\Z/, '')
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
22
lib/puppet/provider/ironic_config/ini_setting.rb
Normal file
22
lib/puppet/provider/ironic_config/ini_setting.rb
Normal file
@ -0,0 +1,22 @@
|
||||
Puppet::Type.type(:ironic_config).provide(
|
||||
:ini_setting,
|
||||
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
|
||||
) do
|
||||
|
||||
def section
|
||||
resource[:name].split('/', 2).first
|
||||
end
|
||||
|
||||
def setting
|
||||
resource[:name].split('/', 2).last
|
||||
end
|
||||
|
||||
def separator
|
||||
'='
|
||||
end
|
||||
|
||||
def file_path
|
||||
'/etc/ironic/ironic.conf'
|
||||
end
|
||||
|
||||
end
|
18
lib/puppet/type/ironic_config.rb
Normal file
18
lib/puppet/type/ironic_config.rb
Normal file
@ -0,0 +1,18 @@
|
||||
Puppet::Type.newtype(:ironic_config) do
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'Section/setting name to manage from ironic.conf'
|
||||
newvalues(/\S+\/\S+/)
|
||||
end
|
||||
|
||||
newproperty(:value) do
|
||||
desc 'The value of the setting to be defined.'
|
||||
munge do |value|
|
||||
value = value.to_s.strip
|
||||
value.capitalize! if value =~ /^(true|false)$/i
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
39
manifests/client.pp
Normal file
39
manifests/client.pp
Normal file
@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
|
||||
# ironic::client
|
||||
#
|
||||
# Manages the ironic client package on systems
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# [*package_ensure*]
|
||||
# (optional) The state of the package
|
||||
# Defaults to present
|
||||
#
|
||||
class ironic::client (
|
||||
$package_ensure = present
|
||||
) {
|
||||
|
||||
include ironic::params
|
||||
|
||||
package { 'python-ironicclient':
|
||||
ensure => $package_ensure,
|
||||
name => $::ironic::params::client_package,
|
||||
}
|
||||
|
||||
}
|
55
manifests/db/mysql.pp
Normal file
55
manifests/db/mysql.pp
Normal file
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# ironic::db::mysql
|
||||
#
|
||||
|
||||
class ironic::db::mysql (
|
||||
$password,
|
||||
$dbname = 'ironic',
|
||||
$user = 'ironic',
|
||||
$host = '127.0.0.1',
|
||||
$allowed_hosts = undef,
|
||||
$charset = 'latin1',
|
||||
$cluster_id = 'localzone'
|
||||
) {
|
||||
|
||||
require mysql::python
|
||||
|
||||
mysql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
require => Class['mysql::config'],
|
||||
}
|
||||
|
||||
# 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 {
|
||||
ironic::db::mysql::host_access { $real_allowed_hosts:
|
||||
user => $user,
|
||||
password => $password,
|
||||
database => $dbname,
|
||||
}
|
||||
}
|
||||
}
|
33
manifests/db/mysql/host_access.pp
Normal file
33
manifests/db/mysql/host_access.pp
Normal file
@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# Used to grant access to the ironic mysql DB
|
||||
#
|
||||
|
||||
define ironic::db::mysql::host_access ($user, $password, $database) {
|
||||
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}"]
|
||||
}
|
||||
}
|
19
manifests/init.pp
Normal file
19
manifests/init.pp
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# ironic
|
||||
#
|
113
manifests/keystone/auth.pp
Normal file
113
manifests/keystone/auth.pp
Normal file
@ -0,0 +1,113 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# ironic::keystone::auth
|
||||
#
|
||||
# Configures Ironic user, service and endpoint in Keystone.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*password*]
|
||||
# (required) Password for Ironic user.
|
||||
#
|
||||
# [*auth_name*]
|
||||
# Username for Ironic service. Defaults to 'ironic'.
|
||||
#
|
||||
# [*email*]
|
||||
# Email for Ironic user. Defaults to 'ironic@localhost'.
|
||||
#
|
||||
# [*tenant*]
|
||||
# Tenant for Ironic user. Defaults to 'services'.
|
||||
#
|
||||
# [*configure_endpoint*]
|
||||
# Should Ironic endpoint be configured? Defaults to 'true'.
|
||||
#
|
||||
# [*service_type*]
|
||||
# Type of service. Defaults to 'baremetal'.
|
||||
#
|
||||
# [*public_protocol*]
|
||||
# Protocol for public endpoint. Defaults to 'http'.
|
||||
#
|
||||
# [*public_address*]
|
||||
# Public address for endpoint. Defaults to '127.0.0.1'.
|
||||
#
|
||||
# [*admin_address*]
|
||||
# Admin address for endpoint. Defaults to '127.0.0.1'.
|
||||
#
|
||||
# [*internal_address*]
|
||||
# Internal address for endpoint. Defaults to '127.0.0.1'.
|
||||
#
|
||||
# [*port*]
|
||||
# Port for endpoint. Defaults to '6385'.
|
||||
#
|
||||
# [*public_port*]
|
||||
# Port for public endpoint. Defaults to $port.
|
||||
#
|
||||
# [*region*]
|
||||
# Region for endpoint. Defaults to 'RegionOne'.
|
||||
#
|
||||
class ironic::keystone::auth (
|
||||
$password,
|
||||
$auth_name = 'ironic',
|
||||
$email = 'ironic@localhost',
|
||||
$tenant = 'services',
|
||||
$configure_endpoint = true,
|
||||
$service_type = 'baremetal',
|
||||
$public_protocol = 'http',
|
||||
$public_address = '127.0.0.1',
|
||||
$admin_address = '127.0.0.1',
|
||||
$internal_address = '127.0.0.1',
|
||||
$port = '6385',
|
||||
$public_port = undef,
|
||||
$region = 'RegionOne'
|
||||
) {
|
||||
|
||||
Keystone_user_role["${auth_name}@${tenant}"] ~> Service <| name == 'ironic-server' |>
|
||||
Keystone_endpoint["${region}/${auth_name}"] ~> Service <| name == 'ironic-server' |>
|
||||
|
||||
if ! $public_port {
|
||||
$real_public_port = $port
|
||||
} else {
|
||||
$real_public_port = $public_port
|
||||
}
|
||||
|
||||
keystone_user { $auth_name:
|
||||
ensure => present,
|
||||
password => $password,
|
||||
email => $email,
|
||||
tenant => $tenant,
|
||||
}
|
||||
keystone_user_role { "${auth_name}@${tenant}":
|
||||
ensure => present,
|
||||
roles => 'admin',
|
||||
}
|
||||
keystone_service { $auth_name:
|
||||
ensure => present,
|
||||
type => $service_type,
|
||||
description => 'Ironic Networking Service',
|
||||
}
|
||||
|
||||
if $configure_endpoint {
|
||||
keystone_endpoint { "${region}/${auth_name}":
|
||||
ensure => present,
|
||||
public_url => "${public_protocol}://${public_address}:${real_public_port}/",
|
||||
internal_url => "http://${internal_address}:${port}/",
|
||||
admin_url => "http://${admin_address}:${port}/",
|
||||
}
|
||||
|
||||
}
|
||||
}
|
46
manifests/params.pp
Normal file
46
manifests/params.pp
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# ironic::params
|
||||
#
|
||||
|
||||
class ironic::params {
|
||||
|
||||
if($::osfamily == 'Redhat') {
|
||||
|
||||
$package_name = 'openstack-ironic'
|
||||
$api_package = false
|
||||
$conductor_package = false
|
||||
$api_service = 'ironic-api'
|
||||
$conductor_service = 'ironic-conductor'
|
||||
$client_package = 'python-ironicclient'
|
||||
|
||||
} elsif($::osfamily == 'Debian') {
|
||||
|
||||
$package_name = 'ironic-common'
|
||||
$api_service = 'ironic-api'
|
||||
$conductor_service = 'ironic-conductor'
|
||||
$api_package = 'ironic-api'
|
||||
$conductor_package = 'ironic-conductor'
|
||||
$client_package = 'python-ironicclient'
|
||||
|
||||
} else {
|
||||
|
||||
fail("Unsupported osfamily ${::osfamily}")
|
||||
|
||||
}
|
||||
}
|
40
spec/classes/ironic_client_spec.rb
Normal file
40
spec/classes/ironic_client_spec.rb
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# Unit tests for ironic::client
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'ironic::client' do
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it { should contain_class('ironic::client') }
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it { should contain_class('ironic::client') }
|
||||
end
|
||||
end
|
103
spec/classes/ironic_db_mysql_spec.rb
Normal file
103
spec/classes/ironic_db_mysql_spec.rb
Normal file
@ -0,0 +1,103 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# Unit tests for ironic::db::mysql
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'ironic::db::mysql' do
|
||||
|
||||
let :pre_condition do
|
||||
'include mysql::server'
|
||||
end
|
||||
|
||||
let :params do
|
||||
{ :password => 'passw0rd' }
|
||||
end
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it { should contain_class('ironic::db::mysql') }
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it { should contain_class('ironic::db::mysql') }
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param to array" do
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironicpass',
|
||||
:allowed_hosts => ['127.0.0.1','%']
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_ironic__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'ironic',
|
||||
:password => 'ironicpass',
|
||||
:database => 'ironic'
|
||||
)}
|
||||
it {should contain_ironic__db__mysql__host_access("%").with(
|
||||
:user => 'ironic',
|
||||
:password => 'ironicpass',
|
||||
:database => 'ironic'
|
||||
)}
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param to string" do
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironicpass2',
|
||||
:allowed_hosts => '192.168.1.1'
|
||||
}
|
||||
end
|
||||
|
||||
it {should contain_ironic__db__mysql__host_access("192.168.1.1").with(
|
||||
:user => 'ironic',
|
||||
:password => 'ironicpass2',
|
||||
:database => 'ironic'
|
||||
)}
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param equals to host param " do
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironicpass2',
|
||||
:allowed_hosts => '127.0.0.1'
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_ironic__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'ironic',
|
||||
:password => 'ironicpass2',
|
||||
:database => 'ironic'
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
19
spec/classes/ironic_init_spec.rb
Normal file
19
spec/classes/ironic_init_spec.rb
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# Unit tests for ironic
|
||||
#
|
120
spec/classes/ironic_keystone_auth_spec.rb
Normal file
120
spec/classes/ironic_keystone_auth_spec.rb
Normal file
@ -0,0 +1,120 @@
|
||||
#
|
||||
# Copyright (C) 2013 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.
|
||||
#
|
||||
# Unit tests for ironic::keystone::auth
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'ironic::keystone::auth' do
|
||||
|
||||
describe 'with default class parameters' do
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironic_password',
|
||||
:tenant => 'foobar'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_user('ironic').with(
|
||||
:ensure => 'present',
|
||||
:password => 'ironic_password',
|
||||
:tenant => 'foobar'
|
||||
) }
|
||||
|
||||
it { should contain_keystone_user_role('ironic@foobar').with(
|
||||
:ensure => 'present',
|
||||
:roles => 'admin'
|
||||
)}
|
||||
|
||||
it { should contain_keystone_service('ironic').with(
|
||||
:ensure => 'present',
|
||||
:type => 'network',
|
||||
:description => 'Ironic Networking Service'
|
||||
) }
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/ironic').with(
|
||||
:ensure => 'present',
|
||||
:public_url => "http://127.0.0.1:6385/",
|
||||
:admin_url => "http://127.0.0.1:6385/",
|
||||
:internal_url => "http://127.0.0.1:6385/"
|
||||
) }
|
||||
|
||||
end
|
||||
|
||||
describe 'when configuring ironic-server' do
|
||||
let :pre_condition do
|
||||
"class { 'ironic::server': auth_password => 'test' }"
|
||||
end
|
||||
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironic_password',
|
||||
:tenant => 'foobar'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/ironic').with_notify('Service[ironic-server]') }
|
||||
end
|
||||
|
||||
describe 'when overriding public_protocol, public_port and public address' do
|
||||
|
||||
let :params do
|
||||
{
|
||||
:password => 'ironic_password',
|
||||
:public_protocol => 'https',
|
||||
:public_port => '80',
|
||||
:public_address => '10.10.10.10',
|
||||
:port => '81',
|
||||
:internal_address => '10.10.10.11',
|
||||
:admin_address => '10.10.10.12'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/ironic').with(
|
||||
:ensure => 'present',
|
||||
:public_url => "https://10.10.10.10:80/",
|
||||
:internal_url => "http://10.10.10.11:81/",
|
||||
:admin_url => "http://10.10.10.12:81/"
|
||||
) }
|
||||
|
||||
end
|
||||
|
||||
describe 'when overriding auth name' do
|
||||
|
||||
let :params do
|
||||
{
|
||||
:password => 'foo',
|
||||
:auth_name => 'ironicy'
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_user('ironicy') }
|
||||
|
||||
it { should contain_keystone_user_role('ironicy@services') }
|
||||
|
||||
it { should contain_keystone_service('ironicy') }
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/ironicy') }
|
||||
|
||||
end
|
||||
|
||||
end
|
25
spec/defines/ironic_db_mysql_host_access_spec.rb
Normal file
25
spec/defines/ironic_db_mysql_host_access_spec.rb
Normal file
@ -0,0 +1,25 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'ironic::db::mysql::host_access' do
|
||||
|
||||
let :pre_condition do
|
||||
'include mysql'
|
||||
end
|
||||
|
||||
let :title do
|
||||
'127.0.0.1'
|
||||
end
|
||||
|
||||
let :params do
|
||||
{ :user => 'ironic',
|
||||
:password => 'passw0rd',
|
||||
:database => 'ironic' }
|
||||
end
|
||||
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it { should contain_database_user('ironic@127.0.0.1') }
|
||||
it { should contain_database_grant('ironic@127.0.0.1/ironic') }
|
||||
end
|
0
spec/fixtures/manifests/site.pp
vendored
Normal file
0
spec/fixtures/manifests/site.pp
vendored
Normal file
5
spec/shared_examples.rb
Normal file
5
spec/shared_examples.rb
Normal file
@ -0,0 +1,5 @@
|
||||
shared_examples_for "a Puppet::Error" do |description|
|
||||
it "with message matching #{description.inspect}" do
|
||||
expect { should have_class_count(1) }.to raise_error(Puppet::Error, description)
|
||||
end
|
||||
end
|
7
spec/spec_helper.rb
Normal file
7
spec/spec_helper.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'puppetlabs_spec_helper/module_spec_helper'
|
||||
require 'shared_examples'
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
||||
c.alias_it_should_behave_like_to :it_raises, 'raises'
|
||||
end
|
111
spec/unit/provider/ironic_spec.rb
Normal file
111
spec/unit/provider/ironic_spec.rb
Normal file
@ -0,0 +1,111 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/ironic'
|
||||
require 'tempfile'
|
||||
|
||||
describe Puppet::Provider::Ironic do
|
||||
|
||||
def klass
|
||||
described_class
|
||||
end
|
||||
|
||||
let :credential_hash do
|
||||
{
|
||||
'auth_host' => '192.168.56.210',
|
||||
'auth_port' => '35357',
|
||||
'auth_protocol' => 'https',
|
||||
'admin_tenant_name' => 'admin_tenant',
|
||||
'admin_user' => 'admin',
|
||||
'admin_password' => 'password',
|
||||
}
|
||||
end
|
||||
|
||||
let :auth_endpoint do
|
||||
'https://192.168.56.210:35357/v2.0/'
|
||||
end
|
||||
|
||||
let :credential_error do
|
||||
/Ironic types will not work/
|
||||
end
|
||||
|
||||
after :each do
|
||||
klass.reset
|
||||
end
|
||||
|
||||
describe 'when determining credentials' do
|
||||
|
||||
it 'should fail if config is empty' do
|
||||
conf = {}
|
||||
klass.expects(:ironic_conf).returns(conf)
|
||||
expect do
|
||||
klass.ironic_credentials
|
||||
end.to raise_error(Puppet::Error, credential_error)
|
||||
end
|
||||
|
||||
it 'should fail if config does not have keystone_authtoken section.' do
|
||||
conf = {'foo' => 'bar'}
|
||||
klass.expects(:ironic_conf).returns(conf)
|
||||
expect do
|
||||
klass.ironic_credentials
|
||||
end.to raise_error(Puppet::Error, credential_error)
|
||||
end
|
||||
|
||||
it 'should fail if config does not contain all auth params' do
|
||||
conf = {'keystone_authtoken' => {'invalid_value' => 'foo'}}
|
||||
klass.expects(:ironic_conf).returns(conf)
|
||||
expect do
|
||||
klass.ironic_credentials
|
||||
end.to raise_error(Puppet::Error, credential_error)
|
||||
end
|
||||
|
||||
it 'should use specified host/port/protocol in the auth endpoint' do
|
||||
conf = {'keystone_authtoken' => credential_hash}
|
||||
klass.expects(:ironic_conf).returns(conf)
|
||||
klass.get_auth_endpoint.should == auth_endpoint
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'when invoking the ironic cli' do
|
||||
|
||||
it 'should set auth credentials in the environment' do
|
||||
authenv = {
|
||||
:OS_AUTH_URL => auth_endpoint,
|
||||
:OS_USERNAME => credential_hash['admin_user'],
|
||||
:OS_TENANT_NAME => credential_hash['admin_tenant_name'],
|
||||
:OS_PASSWORD => credential_hash['admin_password'],
|
||||
}
|
||||
klass.expects(:get_ironic_credentials).with().returns(credential_hash)
|
||||
klass.expects(:withenv).with(authenv)
|
||||
klass.auth_ironic('test_retries')
|
||||
end
|
||||
|
||||
['[Errno 111] Connection refused',
|
||||
'(HTTP 400)'].reverse.each do |valid_message|
|
||||
it "should retry when ironic cli returns with error #{valid_message}" do
|
||||
klass.expects(:get_ironic_credentials).with().returns({})
|
||||
klass.expects(:sleep).with(10).returns(nil)
|
||||
klass.expects(:ironic).twice.with(['test_retries']).raises(
|
||||
Exception, valid_message).then.returns('')
|
||||
klass.auth_ironic('test_retries')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'when listing ironic resources' do
|
||||
|
||||
it 'should exclude the column header' do
|
||||
output = <<-EOT
|
||||
id
|
||||
net1
|
||||
net2
|
||||
EOT
|
||||
klass.expects(:auth_ironic).returns(output)
|
||||
result = klass.list_ironic_resources('foo')
|
||||
result.should eql(['net1', 'net2'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user