Merge pull request #119 from bodepd/fix_folsom_spec_tests
Fix folsom spec tests
This commit is contained in:
@@ -4,8 +4,15 @@ fixtures:
|
||||
"keystone": "git://github.com/puppetlabs/puppetlabs-keystone.git"
|
||||
"mysql": "git://github.com/puppetlabs/puppetlabs-mysql.git"
|
||||
"nova": "git://github.com/puppetlabs/puppetlabs-nova.git"
|
||||
"glance": "git://github.com/puppetlabs/puppetlabs-glance.git"
|
||||
"rabbitmq": "git://github.com/puppetlabs/puppetlabs-rabbitmq"
|
||||
'memcached': 'git://github.com/saz/puppet-memcached'
|
||||
'horizon': 'git://github.com/puppetlabs/puppetlabs-horizon'
|
||||
'quantum': 'git://github.com/bodepd/openstack-quantum-puppet'
|
||||
'cinder': 'git://github.com/puppetlabs/puppetlabs-cinder'
|
||||
"stdlib": "git://github.com/puppetlabs/puppetlabs-stdlib.git"
|
||||
"sysctl": "git://github.com/duritong/puppet-sysctl.git"
|
||||
'inifile': 'git://github.com/cprice-puppet/puppetlabs-inifile'
|
||||
"create_resources": 'git://github.com/puppetlabs/puppetlabs-create_resources'
|
||||
symlinks:
|
||||
"openstack": "#{source_dir}"
|
||||
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
spec/fixtures/modules/*
|
||||
spec/fixtures/manifests/*
|
||||
*swp
|
@@ -57,34 +57,44 @@
|
||||
#
|
||||
#
|
||||
class openstack::all (
|
||||
# Network Required
|
||||
# Required Network
|
||||
$public_address,
|
||||
$public_interface = 'eth0',
|
||||
$private_interface = 'eth1',
|
||||
$public_interface,
|
||||
$private_interface,
|
||||
$admin_email,
|
||||
# required password
|
||||
$mysql_root_password,
|
||||
$admin_password,
|
||||
$rabbit_password,
|
||||
$keystone_db_password,
|
||||
$keystone_admin_token,
|
||||
$glance_db_password,
|
||||
$glance_user_password,
|
||||
$nova_db_password,
|
||||
$nova_user_password,
|
||||
$secret_key,
|
||||
$internal_address = '127.0.0.1',
|
||||
# cinder and quantum password are not required b/c they are
|
||||
# optional. Not sure what to do about this.
|
||||
$cinder_user_password = 'cinder_pass',
|
||||
$cinder_db_password = 'cinder_pass',
|
||||
$quantum_user_password = 'quantum_pass',
|
||||
$quantum_db_password = 'quantum_pass',
|
||||
# Database
|
||||
$mysql_root_password = 'sql_pass',
|
||||
$db_type = 'mysql',
|
||||
$mysql_account_security = true,
|
||||
$allowed_hosts = ['127.0.0.%'],
|
||||
# Keystone
|
||||
$admin_email = 'some_user@some_fake_email_address.foo',
|
||||
$admin_password = 'ChangeMe',
|
||||
$keystone_db_password = 'keystone_pass',
|
||||
$keystone_db_user = 'keystone',
|
||||
$keystone_db_dbname = 'keystone',
|
||||
$keystone_admin_token = 'keystone_admin_token',
|
||||
$keystone_admin_tenant = 'admin',
|
||||
$region = 'RegionOne',
|
||||
# Glance Required
|
||||
$glance_db_password = 'glance_pass',
|
||||
$glance_db_user = 'glance',
|
||||
$glance_db_dbname = 'glance',
|
||||
$glance_user_password = 'glance_pass',
|
||||
# Nova
|
||||
$nova_db_password = 'nova_pass',
|
||||
$nova_db_user = 'nova',
|
||||
$nova_db_dbname = 'nova',
|
||||
$nova_user_password = 'nova_pass',
|
||||
$purge_nova_config = true,
|
||||
# Network
|
||||
$network_manager = 'nova.network.manager.FlatDHCPManager',
|
||||
@@ -96,25 +106,19 @@ class openstack::all (
|
||||
$network_config = {},
|
||||
$quantum = true,
|
||||
# Rabbit
|
||||
$rabbit_password = 'rabbit_pw',
|
||||
$rabbit_user = 'nova',
|
||||
# Horizon
|
||||
$secret_key = 'dummy_secret_key',
|
||||
$cache_server_ip = '127.0.0.1',
|
||||
$cache_server_port = '11211',
|
||||
$swift = false,
|
||||
$horizon_app_links = undef,
|
||||
# if the cinder management components should be installed
|
||||
$cinder = true,
|
||||
$cinder_user_password = 'cinder_user_pass',
|
||||
$cinder_db_password = 'cinder_db_pass',
|
||||
$cinder_db_user = 'cinder',
|
||||
$cinder_db_dbname = 'cinder',
|
||||
$volume_group = 'cinder-volumes',
|
||||
$cinder_test = false,
|
||||
#
|
||||
$quantum_user_password = 'quantum_user_pass',
|
||||
$quantum_db_password = 'quantum_db_pass',
|
||||
$quantum_db_user = 'quantum',
|
||||
$quantum_db_dbname = 'quantum',
|
||||
# Virtaulization
|
||||
@@ -159,7 +163,10 @@ class openstack::all (
|
||||
quantum_db_password => $quantum_db_password,
|
||||
quantum_db_dbname => $quantum_db_dbname,
|
||||
allowed_hosts => $allowed_hosts,
|
||||
enabled => $enabled,
|
||||
}
|
||||
} else {
|
||||
fail("unsupported db type: ${db_type}")
|
||||
}
|
||||
|
||||
####### KEYSTONE ###########
|
||||
@@ -305,7 +312,7 @@ class openstack::all (
|
||||
enabled => $enabled,
|
||||
vnc_enabled => $vnc_enabled,
|
||||
vncserver_proxyclient_address => $internal_address,
|
||||
vncproxy_host => 'localhost',
|
||||
vncproxy_host => $public_address,
|
||||
}
|
||||
|
||||
# Configure libvirt for nova-compute
|
||||
|
@@ -103,7 +103,12 @@ class openstack::compute (
|
||||
|
||||
# if the compute node should be configured as a multi-host
|
||||
# compute installation
|
||||
if $quantum == false {
|
||||
if ! $quantum {
|
||||
|
||||
if ! $fixed_range {
|
||||
fail("Must specify the fixed range when using nova-networks")
|
||||
}
|
||||
|
||||
if $multi_host {
|
||||
include keystone::python
|
||||
nova_config {
|
||||
@@ -157,7 +162,10 @@ class openstack::compute (
|
||||
volume_group => $nova_volume,
|
||||
}
|
||||
|
||||
nova_config { 'volume_api_class': value => 'nova.volume.cinder.API' }
|
||||
# set in nova::api
|
||||
if ! defined(Nova_config['volume_api_class']) {
|
||||
nova_config { 'volume_api_class': value => 'nova.volume.cinder.API' }
|
||||
}
|
||||
} else {
|
||||
# Set up nova-volume
|
||||
}
|
||||
|
@@ -114,7 +114,6 @@ class openstack::controller (
|
||||
$multi_host = false,
|
||||
$auto_assign_floating_ip = false,
|
||||
$network_config = {},
|
||||
$quantum = true,
|
||||
# Rabbit
|
||||
$rabbit_user = 'nova',
|
||||
# Horizon
|
||||
@@ -126,11 +125,13 @@ class openstack::controller (
|
||||
$vnc_enabled = true,
|
||||
# General
|
||||
$verbose = 'False',
|
||||
# cinder
|
||||
# if the cinder management components should be installed
|
||||
$cinder = false,
|
||||
$cinder = true,
|
||||
$cinder_db_user = 'cinder',
|
||||
$cinder_db_dbname = 'cinder',
|
||||
#
|
||||
# quantum
|
||||
$quantum = true,
|
||||
$quantum_db_user = 'quantum',
|
||||
$quantum_db_dbname = 'quantum',
|
||||
$enabled = true
|
||||
@@ -144,7 +145,7 @@ class openstack::controller (
|
||||
if $admin_address {
|
||||
$admin_address_real = $admin_address
|
||||
} else {
|
||||
$admin_address_real = $public_address
|
||||
$admin_address_real = $internal_address_real
|
||||
}
|
||||
|
||||
# Ensure things are run in order
|
||||
@@ -182,6 +183,8 @@ class openstack::controller (
|
||||
allowed_hosts => $allowed_hosts,
|
||||
enabled => $enabled,
|
||||
}
|
||||
} else {
|
||||
fail("Unsupported db : ${db_type}")
|
||||
}
|
||||
|
||||
####### KEYSTONE ###########
|
||||
@@ -198,7 +201,7 @@ class openstack::controller (
|
||||
admin_password => $admin_password,
|
||||
public_address => $public_address,
|
||||
internal_address => $internal_address_real,
|
||||
admin_address => $admin_address,
|
||||
admin_address => $admin_address_real,
|
||||
region => $region,
|
||||
glance_user_password => $glance_user_password,
|
||||
nova_user_password => $nova_user_password,
|
||||
|
@@ -51,7 +51,6 @@ class openstack::db::mysql (
|
||||
# Nova
|
||||
$nova_db_user = 'nova',
|
||||
$nova_db_dbname = 'nova',
|
||||
$allowed_hosts = false,
|
||||
# Cinder
|
||||
$cinder = true,
|
||||
$cinder_db_user = 'cinder',
|
||||
@@ -60,6 +59,7 @@ class openstack::db::mysql (
|
||||
$quantum = true,
|
||||
$quantum_db_user = 'quantum',
|
||||
$quantum_db_dbname = 'quantum',
|
||||
$allowed_hosts = false,
|
||||
$enabled = true
|
||||
) {
|
||||
|
||||
|
@@ -157,8 +157,8 @@ class openstack::keystone (
|
||||
}
|
||||
|
||||
class { '::keystone':
|
||||
verbose => $verbose,
|
||||
debug => $verbose,
|
||||
verbose => $verbose,
|
||||
debug => $verbose,
|
||||
catalog_type => 'sql',
|
||||
admin_token => $admin_token,
|
||||
enabled => $enabled,
|
||||
|
@@ -57,7 +57,7 @@ class openstack::nova::controller (
|
||||
# General
|
||||
$keystone_host = '127.0.0.1',
|
||||
$verbose = 'False',
|
||||
$enabled = true,
|
||||
$enabled = true
|
||||
) {
|
||||
|
||||
# Configure the db string
|
||||
|
@@ -4,8 +4,14 @@ describe 'openstack::compute' do
|
||||
|
||||
let :default_params do
|
||||
{
|
||||
:private_interface => 'eth0',
|
||||
:internal_address => '0.0.0.0',
|
||||
:private_interface => 'eth0',
|
||||
:internal_address => '0.0.0.0',
|
||||
:nova_user_password => 'nova_pass',
|
||||
:rabbit_password => 'rabbit_pw',
|
||||
:sql_connection => 'mysql://user:pass@host/dbname/',
|
||||
:cinder_sql_connection => 'mysql://user:pass@host/dbname/',
|
||||
:quantum => false,
|
||||
:fixed_range => '10.0.0.0/16',
|
||||
}
|
||||
end
|
||||
|
||||
@@ -22,13 +28,13 @@ describe 'openstack::compute' do
|
||||
end
|
||||
it {
|
||||
should contain_class('nova').with(
|
||||
:sql_connection => false,
|
||||
:rabbit_host => false,
|
||||
:sql_connection => 'mysql://user:pass@host/dbname/',
|
||||
:rabbit_host => '127.0.0.1',
|
||||
:rabbit_userid => 'nova',
|
||||
:rabbit_password => 'rabbit_pw',
|
||||
:image_service => 'nova.image.glance.GlanceImageService',
|
||||
:glance_api_servers => false,
|
||||
:verbose => false
|
||||
:verbose => 'False'
|
||||
)
|
||||
should contain_class('nova::compute').with(
|
||||
:enabled => true,
|
||||
@@ -43,8 +49,6 @@ describe 'openstack::compute' do
|
||||
should contain_nova_config('multi_host').with( :value => 'False' )
|
||||
should contain_nova_config('send_arp_for_ha').with( :value => 'False' )
|
||||
should_not contain_class('nova::api')
|
||||
should_not contain_class('nova::volume')
|
||||
should_not contain_class('nova::volume::iscsi')
|
||||
should contain_class('nova::network').with({
|
||||
:enabled => false,
|
||||
:install_service => false,
|
||||
@@ -82,7 +86,7 @@ describe 'openstack::compute' do
|
||||
let :params do
|
||||
default_params.merge(override_params)
|
||||
end
|
||||
it {
|
||||
it do
|
||||
should contain_class('nova').with(
|
||||
:sql_connection => 'mysql://user:passwd@host/name',
|
||||
:rabbit_host => 'my_host',
|
||||
@@ -105,8 +109,6 @@ describe 'openstack::compute' do
|
||||
should contain_nova_config('multi_host').with( :value => 'False' )
|
||||
should contain_nova_config('send_arp_for_ha').with( :value => 'False' )
|
||||
should_not contain_class('nova::api')
|
||||
should_not contain_class('nova::volume')
|
||||
should_not contain_class('nova::volume::iscsi')
|
||||
should contain_class('nova::network').with({
|
||||
:enabled => false,
|
||||
:install_service => false,
|
||||
@@ -116,7 +118,7 @@ describe 'openstack::compute' do
|
||||
:enabled => false,
|
||||
:install_service => false
|
||||
})
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "when enabling volume management" do
|
||||
@@ -129,71 +131,65 @@ describe 'openstack::compute' do
|
||||
it do
|
||||
should contain_nova_config('multi_host').with({ 'value' => 'False'})
|
||||
should_not contain_class('nova::api')
|
||||
should contain_class('nova::volume').with(:enabled => true)
|
||||
should contain_class('nova::network').with({
|
||||
'enabled' => false,
|
||||
'install_service' => false
|
||||
})
|
||||
end
|
||||
describe 'with default volume settings' do
|
||||
it { should contain_class('nova::volume::iscsi').with(
|
||||
:volume_group => 'nova-volumes',
|
||||
:iscsi_ip_address => '0.0.0.0'
|
||||
)}
|
||||
end
|
||||
describe 'when overriding volume parameters' do
|
||||
let :params do
|
||||
default_params.merge({
|
||||
:manage_volumes => true,
|
||||
:nova_volume => 'nova-volumes2',
|
||||
:internal_address => '127.0.0.1'
|
||||
})
|
||||
end
|
||||
it { should contain_class('nova::volume::iscsi').with(
|
||||
:volume_group => 'nova-volumes2',
|
||||
:iscsi_ip_address => '127.0.0.1'
|
||||
) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "when configuring for multi host" do
|
||||
let :params do
|
||||
default_params.merge({
|
||||
:multi_host => true,
|
||||
:public_interface => 'eth0'
|
||||
})
|
||||
end
|
||||
|
||||
it {
|
||||
should contain_class('keystone::python')
|
||||
should contain_nova_config('multi_host').with({ 'value' => 'True'})
|
||||
should contain_nova_config('send_arp_for_ha').with(:value => 'True')
|
||||
should_not contain_class('nova::volume')
|
||||
should_not contain_class('nova::volume::iscsi')
|
||||
should contain_class('nova::network').with({
|
||||
'enabled' => true,
|
||||
'install_service' => true
|
||||
})
|
||||
}
|
||||
describe 'with defaults' do
|
||||
it { should contain_class('nova::api').with(
|
||||
:enabled => true,
|
||||
:admin_tenant_name => 'services',
|
||||
:admin_user => 'nova',
|
||||
:admin_password => 'nova_pass'
|
||||
)}
|
||||
end
|
||||
describe 'when overrding nova volumes' do
|
||||
describe 'when quantum is false' do
|
||||
describe 'configuring for multi host' do
|
||||
let :params do
|
||||
default_params.merge({
|
||||
:multi_host => true,
|
||||
:public_interface => 'eth0',
|
||||
:nova_user_password => 'foo'
|
||||
:multi_host => true,
|
||||
:public_interface => 'eth0',
|
||||
:quantum => false
|
||||
})
|
||||
end
|
||||
it { should contain_class('nova::api').with(
|
||||
:admin_password => 'foo'
|
||||
)}
|
||||
|
||||
it 'should configure nova for multi-host' do
|
||||
#should contain_class('keystone::python')
|
||||
should contain_nova_config('multi_host').with(:value => 'True')
|
||||
should contain_nova_config('send_arp_for_ha').with( :value => 'True')
|
||||
should contain_class('nova::network').with({
|
||||
'enabled' => true,
|
||||
'install_service' => true
|
||||
})
|
||||
end
|
||||
describe 'with defaults' do
|
||||
it { should contain_class('nova::api').with(
|
||||
:enabled => true,
|
||||
:admin_tenant_name => 'services',
|
||||
:admin_user => 'nova',
|
||||
:admin_password => 'nova_pass'
|
||||
)}
|
||||
end
|
||||
end
|
||||
describe 'when overriding network params' do
|
||||
let :params do
|
||||
default_params.merge({
|
||||
:multi_host => true,
|
||||
:public_interface => 'eth0',
|
||||
:manage_volumes => true,
|
||||
:private_interface => 'eth1',
|
||||
:public_interface => 'eth2',
|
||||
:fixed_range => '12.0.0.0/24',
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:network_config => {'vlan_interface' => 'eth0'}
|
||||
})
|
||||
end
|
||||
it { should contain_class('nova::network').with({
|
||||
:private_interface => 'eth1',
|
||||
:public_interface => 'eth2',
|
||||
:fixed_range => '12.0.0.0/24',
|
||||
:floating_range => false,
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:config_overrides => {'vlan_interface' => 'eth0'},
|
||||
:create_networks => false,
|
||||
'enabled' => true,
|
||||
'install_service' => true
|
||||
})}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -221,8 +217,6 @@ describe 'openstack::compute' do
|
||||
it {
|
||||
should contain_nova_config('multi_host').with({ 'value' => 'True'})
|
||||
should contain_class('nova::api')
|
||||
should contain_class('nova::volume')
|
||||
should contain_class('nova::volume::iscsi')
|
||||
should contain_class('nova::network').with({
|
||||
'enabled' => true,
|
||||
'install_service' => true
|
||||
@@ -230,30 +224,4 @@ describe 'openstack::compute' do
|
||||
}
|
||||
end
|
||||
|
||||
describe 'when overriding network params' do
|
||||
let :params do
|
||||
default_params.merge({
|
||||
:multi_host => true,
|
||||
:public_interface => 'eth0',
|
||||
:manage_volumes => true,
|
||||
:private_interface => 'eth1',
|
||||
:public_interface => 'eth2',
|
||||
:fixed_range => '12.0.0.0/24',
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:network_config => {'vlan_interface' => 'eth0'}
|
||||
})
|
||||
end
|
||||
it { should contain_class('nova::network').with({
|
||||
:private_interface => 'eth1',
|
||||
:public_interface => 'eth2',
|
||||
:fixed_range => '12.0.0.0/24',
|
||||
:floating_range => false,
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:config_overrides => {'vlan_interface' => 'eth0'},
|
||||
:create_networks => false,
|
||||
'enabled' => true,
|
||||
'install_service' => true
|
||||
})}
|
||||
|
||||
end
|
||||
end
|
||||
|
@@ -1,13 +1,25 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'openstack::controller' do
|
||||
|
||||
# minimum set of default parameters
|
||||
let :default_params do
|
||||
{
|
||||
:private_interface => 'eth0',
|
||||
:public_interface => 'eth1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:public_address => '10.0.0.1',
|
||||
:export_resources => false,
|
||||
:private_interface => 'eth0',
|
||||
:public_interface => 'eth1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:public_address => '10.0.0.1',
|
||||
:admin_email => 'some_user@some_fake_email_address.foo',
|
||||
:admin_password => 'ChangeMe',
|
||||
:rabbit_password => 'rabbit_pw',
|
||||
:keystone_db_password => 'keystone_pass',
|
||||
:keystone_admin_token => 'keystone_admin_token',
|
||||
:glance_db_password => 'glance_pass',
|
||||
:glance_user_password => 'glance_pass',
|
||||
:nova_db_password => 'nova_pass',
|
||||
:nova_user_password => 'nova_pass',
|
||||
:secret_key => 'secret_key',
|
||||
:quantum => false,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -15,307 +27,443 @@ describe 'openstack::controller' do
|
||||
{
|
||||
:operatingsystem => 'Ubuntu',
|
||||
:osfamily => 'Debian',
|
||||
:concat_basedir => '/tmp/',
|
||||
:puppetversion => '2.7.x',
|
||||
:memorysize => '2GB',
|
||||
:processorcount => '2'
|
||||
}
|
||||
end
|
||||
|
||||
let :params do
|
||||
default_params
|
||||
end
|
||||
|
||||
it { should_not contain_nova_config('auto_assign_floating_ip') }
|
||||
describe 'when auto assign floating ip is assigned' do
|
||||
let :params do
|
||||
default_params.merge(:auto_assign_floating_ip => 'true')
|
||||
context 'database' do
|
||||
|
||||
context 'with unsupported db type' do
|
||||
|
||||
let :params do
|
||||
default_params.merge({:db_type => 'sqlite'})
|
||||
end
|
||||
|
||||
it do
|
||||
expect { subject }.to raise_error(Puppet::Error)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with default mysql params' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:enabled => true,
|
||||
:db_type => 'mysql',
|
||||
:quantum => true,
|
||||
:cinder => true
|
||||
)
|
||||
end
|
||||
|
||||
it { should contain_class('mysql::server').with(
|
||||
:config_hash => {'bind_address' => '0.0.0.0', 'root_password' => 'sql_pass' },
|
||||
:enabled => true
|
||||
)
|
||||
}
|
||||
|
||||
it 'should contain openstack db config' do
|
||||
should contain_class('keystone::db::mysql').with(
|
||||
:user => 'keystone',
|
||||
:password => 'keystone_pass',
|
||||
:dbname => 'keystone',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
should contain_class('glance::db::mysql').with(
|
||||
:user => 'glance',
|
||||
:password => 'glance_pass',
|
||||
:dbname => 'glance',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
should contain_class('nova::db::mysql').with(
|
||||
:user => 'nova',
|
||||
:password => 'nova_pass',
|
||||
:dbname => 'nova',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
should contain_class('cinder::db::mysql').with(
|
||||
:user => 'cinder',
|
||||
:password => 'cinder_pass',
|
||||
:dbname => 'cinder',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
should contain_class('quantum::db::mysql').with(
|
||||
:user => 'quantum',
|
||||
:password => 'quantum_pass',
|
||||
:dbname => 'quantum',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
it { should contain_class('mysql::server::account_security')}
|
||||
|
||||
end
|
||||
|
||||
context 'when cinder and quantum are false' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:quantum => false,
|
||||
:cinder => false
|
||||
)
|
||||
end
|
||||
it do
|
||||
should_not contain_class('quantum::db::mysql')
|
||||
should_not contain_class('cinder::db::mysql')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'when not enabled' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(
|
||||
{:enabled => false}
|
||||
)
|
||||
end
|
||||
|
||||
it { should contain_class('mysql::server').with(
|
||||
:config_hash => {'bind_address' => '0.0.0.0', 'root_password' => 'sql_pass' },
|
||||
:enabled => false
|
||||
)
|
||||
}
|
||||
|
||||
['keystone', 'nova', 'glance', 'cinder', 'quantum'].each do |x|
|
||||
it { should_not contain_class("#{x}::db::mysql") }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account secutiry is not enabled' do
|
||||
let :params do
|
||||
default_params.merge(
|
||||
{:mysql_account_security => false}
|
||||
)
|
||||
end
|
||||
|
||||
it { should_not contain_class('mysql::server::account_security')}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'keystone' do
|
||||
|
||||
context 'with default params' do
|
||||
|
||||
let :params do
|
||||
default_params
|
||||
end
|
||||
|
||||
it { should contain_class('keystone').with(
|
||||
:verbose => 'False',
|
||||
:debug => 'False',
|
||||
:catalog_type => 'sql',
|
||||
:enabled => true,
|
||||
:admin_token => 'keystone_admin_token',
|
||||
:sql_connection => "mysql://keystone:keystone_pass@127.0.0.1/keystone"
|
||||
) }
|
||||
|
||||
it 'should contain endpoints' do
|
||||
should contain_class('keystone::roles::admin').with(
|
||||
:email => 'some_user@some_fake_email_address.foo',
|
||||
:password => 'ChangeMe',
|
||||
:admin_tenant => 'admin'
|
||||
)
|
||||
should contain_class('keystone::endpoint').with(
|
||||
:public_address => '10.0.0.1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:admin_address => '127.0.0.1',
|
||||
:region => 'RegionOne'
|
||||
)
|
||||
{
|
||||
'nova' => 'nova_pass',
|
||||
'cinder' => 'cinder_pass',
|
||||
'glance' => 'glance_pass'
|
||||
|
||||
}.each do |type, pw|
|
||||
should contain_class("#{type}::keystone::auth").with(
|
||||
:password => pw,
|
||||
:public_address => '10.0.0.1',
|
||||
:internal_address => '10.0.0.1',
|
||||
:admin_address => '10.0.0.1',
|
||||
:region => 'RegionOne'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
context 'when not enabled' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(:enabled => false)
|
||||
end
|
||||
|
||||
it 'should not configure endpoints' do
|
||||
should contain_class('keystone').with(:enabled => false)
|
||||
should_not contain_class('keystone::roles::admin')
|
||||
should_not contain_class('keystone::endpoint')
|
||||
should_not contain_class('glance::keystone::auth')
|
||||
should_not contain_class('nova::keystone::auth')
|
||||
end
|
||||
end
|
||||
it { should contain_nova_config('auto_assign_floating_ip').with(:value => 'True')}
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_class('mysql::server').with(
|
||||
:config_hash => {'bind_address' => '0.0.0.0', 'root_password' => 'sql_pass' }
|
||||
)
|
||||
should contain_class('memcached').with(
|
||||
:listen_ip => '127.0.0.1'
|
||||
)
|
||||
end
|
||||
|
||||
describe 'when enabled' do
|
||||
it 'should contain enabled database configs' do
|
||||
should contain_class('mysql::server').with(
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('keystone::db::mysql').with(
|
||||
:password => 'keystone_pass'
|
||||
)
|
||||
should contain_class('glance::db::mysql').with(
|
||||
:host => '127.0.0.1',
|
||||
:password => 'glance_pass',
|
||||
:before => ["Class[Glance::Registry]", "Exec[glance-manage db_sync]"]
|
||||
)
|
||||
should contain_class('nova::db::mysql').with(
|
||||
:password => 'nova_pass',
|
||||
:host => '127.0.0.1',
|
||||
:allowed_hosts => '%'
|
||||
)
|
||||
|
||||
|
||||
context 'config for glance' do
|
||||
|
||||
context 'when enabled' do
|
||||
it 'should contain enabled glance with defaults' do
|
||||
|
||||
should contain_class('glance::api').with(
|
||||
:verbose => 'False',
|
||||
:debug => 'False',
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass',
|
||||
:sql_connection => 'mysql://glance:glance_pass@127.0.0.1/glance',
|
||||
:enabled => true
|
||||
)
|
||||
|
||||
should contain_class('glance::registry').with(
|
||||
:verbose => 'False',
|
||||
:debug => 'False',
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass',
|
||||
:sql_connection => "mysql://glance:glance_pass@127.0.0.1/glance",
|
||||
:enabled => true
|
||||
)
|
||||
|
||||
should contain_class('glance::backend::file')
|
||||
end
|
||||
end
|
||||
it 'should contain enabled keystone configs with defaults' do
|
||||
context 'when not enabled' do
|
||||
|
||||
should contain_class('keystone').with(
|
||||
:admin_token => 'keystone_admin_token',
|
||||
:bind_host => '0.0.0.0',
|
||||
:verbose => false,
|
||||
:debug => false,
|
||||
:catalog_type => 'sql',
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('keystone::config::mysql').with(
|
||||
:password => 'keystone_pass'
|
||||
)
|
||||
should contain_class('keystone::roles::admin').with(
|
||||
:email => 'some_user@some_fake_email_address.foo',
|
||||
:password => 'ChangeMe'
|
||||
)
|
||||
should contain_class('keystone::endpoint').with(
|
||||
:public_address => '10.0.0.1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:admin_address => '127.0.0.1'
|
||||
)
|
||||
should contain_class('glance::keystone::auth').with(
|
||||
:password => 'glance_pass',
|
||||
:public_address => '10.0.0.1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:admin_address => '127.0.0.1'
|
||||
#:before => ['Class[glance::api]', 'Class[glance::registry]']
|
||||
)
|
||||
should contain_class('nova::keystone::auth').with(
|
||||
:password => 'nova_pass',
|
||||
:public_address => '10.0.0.1',
|
||||
:internal_address => '127.0.0.1',
|
||||
:admin_address => '127.0.0.1'
|
||||
#:before => 'Class[nova::api]'
|
||||
)
|
||||
should contain_class('glance::api').with(
|
||||
:verbose => false,
|
||||
:debug => false,
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass',
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('glance::backend::file')
|
||||
let :params do
|
||||
default_params.merge(:enabled => false)
|
||||
end
|
||||
|
||||
should contain_class('glance::registry').with(
|
||||
:verbose => false,
|
||||
:debug => false,
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass',
|
||||
:sql_connection => "mysql://glance:glance_pass@127.0.0.1/glance",
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('nova::rabbitmq').with(
|
||||
:userid => 'nova',
|
||||
:password => 'rabbit_pw',
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('nova').with(
|
||||
:sql_connection => 'mysql://nova:nova_pass@127.0.0.1/nova',
|
||||
:rabbit_host => '127.0.0.1',
|
||||
:rabbit_userid => 'nova',
|
||||
:rabbit_password => 'rabbit_pw',
|
||||
:image_service => 'nova.image.glance.GlanceImageService',
|
||||
:glance_api_servers => '10.0.0.1:9292',
|
||||
:verbose => false
|
||||
)
|
||||
should contain_class('nova::api').with(
|
||||
:enabled => true,
|
||||
:admin_tenant_name => 'services',
|
||||
:admin_user => 'nova',
|
||||
:admin_password => 'nova_pass'
|
||||
)
|
||||
should contain_class('nova::cert').with(:enabled => true)
|
||||
should contain_class('nova::consoleauth').with(:enabled => true)
|
||||
should contain_class('nova::scheduler').with(:enabled => true)
|
||||
should contain_class('nova::objectstore').with(:enabled => true)
|
||||
should contain_class('nova::vncproxy').with(:enabled => true)
|
||||
should contain_class('horizon').with(
|
||||
:secret_key => 'dummy_secret_key',
|
||||
:cache_server_ip => '127.0.0.1',
|
||||
:cache_server_port => '11211',
|
||||
:swift => false,
|
||||
:quantum => false,
|
||||
:horizon_app_links => false
|
||||
)
|
||||
it 'should disable glance services' do
|
||||
should contain_class('glance::api').with(
|
||||
:enabled => false
|
||||
)
|
||||
|
||||
should contain_class('glance::registry').with(
|
||||
:enabled => false
|
||||
)
|
||||
end
|
||||
end
|
||||
describe 'when overriding params' do
|
||||
context 'when params are overridden' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:keystone_db_password => 'pass',
|
||||
:glance_db_password => 'pass2',
|
||||
:nova_db_password => 'pass3',
|
||||
:verbose => true,
|
||||
:keystone_admin_token => 'foo',
|
||||
:nova_user_password => 'pass5',
|
||||
:glance_user_password => 'pass6',
|
||||
:admin_email => 'dan@puppetlabs.com',
|
||||
:admin_address => '127.0.0.2',
|
||||
:admin_password => 'pass7',
|
||||
:rabbit_user => 'rabby',
|
||||
:rabbit_password => 'rabby_pw',
|
||||
:fixed_range => '10.0.0.0/24',
|
||||
:floating_range => '11.0.0.0/24',
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:network_config => {'vlan_interface' => 'eth4'},
|
||||
:num_networks => 2,
|
||||
:secret_key => 'real_secret_key',
|
||||
:cache_server_ip => '127.0.0.2',
|
||||
:cache_server_port => '11212',
|
||||
:swift => true,
|
||||
:quantum => true,
|
||||
:horizon_app_links => true,
|
||||
:glance_api_servers => '127.0.0.1:9292'
|
||||
)
|
||||
end
|
||||
it 'should override db config' do
|
||||
should contain_class('keystone::db::mysql').with(
|
||||
:password => 'pass'
|
||||
)
|
||||
should contain_class('glance::db::mysql').with(
|
||||
:password => 'pass2'
|
||||
)
|
||||
should contain_class('nova::db::mysql').with(
|
||||
:password => 'pass3'
|
||||
:verbose => 'False',
|
||||
:glance_user_password => 'glance_pass2',
|
||||
:glance_db_password => 'glance_pass3',
|
||||
:db_host => '127.0.0.2',
|
||||
:glance_db_user => 'dan',
|
||||
:glance_db_dbname => 'name',
|
||||
:db_host => '127.0.0.2'
|
||||
)
|
||||
end
|
||||
|
||||
it 'should override keystone config' do
|
||||
should contain_class('keystone').with(
|
||||
:verbose => true,
|
||||
:debug => true,
|
||||
:admin_token => 'foo'
|
||||
)
|
||||
should contain_class('keystone::config::mysql').with(
|
||||
:password => 'pass'
|
||||
)
|
||||
should contain_class('keystone::endpoint').with(
|
||||
:admin_address => '127.0.0.2'
|
||||
)
|
||||
should contain_class('keystone::roles::admin').with(
|
||||
:email => 'dan@puppetlabs.com',
|
||||
:password => 'pass7'
|
||||
)
|
||||
should contain_class('glance::keystone::auth').with(
|
||||
:password => 'pass6',
|
||||
:admin_address => '127.0.0.2'
|
||||
)
|
||||
should contain_class('nova::keystone::auth').with(
|
||||
:password => 'pass5',
|
||||
:admin_address => '127.0.0.2'
|
||||
)
|
||||
end
|
||||
it 'should override glance config' do
|
||||
it 'should override params for glance' do
|
||||
should contain_class('glance::api').with(
|
||||
:verbose => true,
|
||||
:debug => true,
|
||||
:keystone_password => 'pass6',
|
||||
:enabled => true
|
||||
:verbose => 'False',
|
||||
:debug => 'False',
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass2',
|
||||
:sql_connection => 'mysql://dan:glance_pass3@127.0.0.2/name'
|
||||
)
|
||||
|
||||
should contain_class('glance::registry').with(
|
||||
:verbose => true,
|
||||
:debug => true,
|
||||
:keystone_password => 'pass6',
|
||||
:sql_connection => "mysql://glance:pass2@127.0.0.1/glance",
|
||||
:enabled => true
|
||||
:verbose => 'False',
|
||||
:debug => 'False',
|
||||
:auth_type => 'keystone',
|
||||
:auth_host => '127.0.0.1',
|
||||
:auth_port => '35357',
|
||||
:keystone_tenant => 'services',
|
||||
:keystone_user => 'glance',
|
||||
:keystone_password => 'glance_pass2',
|
||||
:sql_connection => "mysql://dan:glance_pass3@127.0.0.2/name"
|
||||
)
|
||||
end
|
||||
it 'should override nova config' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'config for nova' do
|
||||
let :facts do
|
||||
{
|
||||
:operatingsystem => 'Ubuntu',
|
||||
:osfamily => 'Debian',
|
||||
:puppetversion => '2.7.x',
|
||||
:memorysize => '2GB',
|
||||
:processorcount => '2'
|
||||
}
|
||||
end
|
||||
|
||||
context 'with default params' do
|
||||
|
||||
it 'should contain enabled nova services' do
|
||||
should contain_class('nova::rabbitmq').with(
|
||||
:userid => 'rabby',
|
||||
:password => 'rabby_pw',
|
||||
:userid => 'nova',
|
||||
:password => 'rabbit_pw',
|
||||
:enabled => true
|
||||
)
|
||||
should contain_class('nova').with(
|
||||
:sql_connection => 'mysql://nova:pass3@127.0.0.1/nova',
|
||||
:sql_connection => 'mysql://nova:nova_pass@127.0.0.1/nova',
|
||||
:rabbit_host => '127.0.0.1',
|
||||
:rabbit_userid => 'rabby',
|
||||
:rabbit_password => 'rabby_pw',
|
||||
:rabbit_userid => 'nova',
|
||||
:rabbit_password => 'rabbit_pw',
|
||||
:image_service => 'nova.image.glance.GlanceImageService',
|
||||
:glance_api_servers => '127.0.0.1:9292',
|
||||
:verbose => true
|
||||
:glance_api_servers => '10.0.0.1:9292',
|
||||
:verbose => 'False'
|
||||
)
|
||||
should contain_class('nova::api').with(
|
||||
:enabled => true,
|
||||
:admin_tenant_name => 'services',
|
||||
:admin_user => 'nova',
|
||||
:admin_password => 'pass5'
|
||||
)
|
||||
should contain_class('nova::network').with(
|
||||
:fixed_range => '10.0.0.0/24',
|
||||
:floating_range => '11.0.0.0/24',
|
||||
:network_manager => 'nova.network.manager.VlanManager',
|
||||
:config_overrides => {'vlan_interface' => 'eth4'},
|
||||
:num_networks => 2
|
||||
:admin_password => 'nova_pass'
|
||||
)
|
||||
should contain_class('nova::cert').with(:enabled => true)
|
||||
should contain_class('nova::consoleauth').with(:enabled => true)
|
||||
should contain_class('nova::scheduler').with(:enabled => true)
|
||||
should contain_class('nova::objectstore').with(:enabled => true)
|
||||
should contain_class('nova::vncproxy').with(:enabled => true)
|
||||
end
|
||||
describe 'it should override horizon params' do
|
||||
it { should contain_class('horizon').with(
|
||||
:secret_key => 'real_secret_key',
|
||||
:cache_server_ip => '127.0.0.2',
|
||||
:cache_server_port => '11212',
|
||||
:swift => true,
|
||||
:quantum => true,
|
||||
:horizon_app_links => true
|
||||
)}
|
||||
it { should_not contain_nova_config('auto_assign_floating_ip') }
|
||||
end
|
||||
context 'when auto assign floating ip is assigned' do
|
||||
let :params do
|
||||
default_params.merge(:auto_assign_floating_ip => 'true')
|
||||
end
|
||||
it { should contain_nova_config('auto_assign_floating_ip').with(:value => 'True')}
|
||||
end
|
||||
context 'when not enabled' do
|
||||
let :params do
|
||||
default_params.merge(:enabled => false)
|
||||
end
|
||||
it 'should disable everything' do
|
||||
should contain_class('nova::rabbitmq').with(:enabled => false)
|
||||
should contain_class('nova::api').with(:enabled => false)
|
||||
should contain_class('nova::cert').with(:enabled => false)
|
||||
should contain_class('nova::consoleauth').with(:enabled => false)
|
||||
should contain_class('nova::scheduler').with(:enabled => false)
|
||||
should contain_class('nova::objectstore').with(:enabled => false)
|
||||
should contain_class('nova::vncproxy').with(:enabled => false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when not enabled' do
|
||||
let :params do
|
||||
default_params.merge(:enabled => false)
|
||||
end
|
||||
it do
|
||||
should contain_class('mysql::server').with(
|
||||
:enabled => false
|
||||
|
||||
context 'config for horizon' do
|
||||
|
||||
it 'should contain enabled horizon' do
|
||||
should contain_class('horizon').with(
|
||||
:secret_key => 'secret_key',
|
||||
:cache_server_ip => '127.0.0.1',
|
||||
:cache_server_port => '11211',
|
||||
:swift => false,
|
||||
:quantum => false,
|
||||
:horizon_app_links => false
|
||||
)
|
||||
should_not contain_class('keystone::db::mysql')
|
||||
should_not contain_class('glance::db::mysql')
|
||||
should_not contain_class('nova::db::mysql')
|
||||
should contain_class('keystone::config::mysql')
|
||||
should contain_class('keystone').with(:enabled => false)
|
||||
should_not contain_class('keystone::roles::admin')
|
||||
should_not contain_class('keystone::endpoint')
|
||||
should_not contain_class('glance::keystone::auth')
|
||||
should_not contain_class('nova::keystone::auth')
|
||||
should contain_class('glance::api').with(:enabled => false)
|
||||
should contain_class('glance::backend::file')
|
||||
should contain_class('glance::registry').with(:enabled => false)
|
||||
should contain_class('nova::rabbitmq').with(:enabled => false)
|
||||
should contain_class('nova::api').with(:enabled => false)
|
||||
should contain_class('nova::cert').with(:enabled => false)
|
||||
should contain_class('nova::consoleauth').with(:enabled => false)
|
||||
should contain_class('nova::scheduler').with(:enabled => false)
|
||||
should contain_class('nova::objectstore').with(:enabled => false)
|
||||
should contain_class('nova::vncproxy').with(:enabled => false)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'nova network config' do
|
||||
context 'cinder' do
|
||||
|
||||
describe 'when enabled' do
|
||||
context 'when disabled' do
|
||||
let :params do
|
||||
default_params.merge(:cinder => false)
|
||||
end
|
||||
it 'should not contain cinder classes' do
|
||||
should_not contain_class('cinder::base')
|
||||
should_not contain_class('cinder::api')
|
||||
should_not contain_class('cinder:"scheduler')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when multihost is not set' do
|
||||
context 'when enabled' do
|
||||
let :params do
|
||||
default_params
|
||||
end
|
||||
it 'should configure cinder using defaults' do
|
||||
should contain_class('cinder::base').with(
|
||||
:verbose => 'False',
|
||||
:sql_connection => 'mysql://cinder:cinder_pass@127.0.0.1/cinder?charset=utf8',
|
||||
:rabbit_password => 'rabbit_pw'
|
||||
)
|
||||
should contain_class('cinder::api').with_keystone_password('cinder_pass')
|
||||
should contain_class('cinder::scheduler')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when overriding config' do
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:verbose => 'True',
|
||||
:rabbit_password => 'rabbit_pw2',
|
||||
:cinder_user_password => 'foo',
|
||||
:cinder_db_password => 'bar',
|
||||
:cinder_db_user => 'baz',
|
||||
:cinder_db_dbname => 'blah',
|
||||
:db_host => '127.0.0.2'
|
||||
)
|
||||
end
|
||||
it 'should configure cinder using defaults' do
|
||||
should contain_class('cinder::base').with(
|
||||
:verbose => 'True',
|
||||
:sql_connection => 'mysql://baz:bar@127.0.0.2/blah?charset=utf8',
|
||||
:rabbit_password => 'rabbit_pw2'
|
||||
)
|
||||
should contain_class('cinder::api').with_keystone_password('foo')
|
||||
should contain_class('cinder::scheduler')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'network config' do
|
||||
|
||||
context 'when quantum' do
|
||||
|
||||
let :params do
|
||||
default_params.merge(:quantum => true)
|
||||
end
|
||||
|
||||
it { should_not contain_class('nova::network') }
|
||||
|
||||
end
|
||||
|
||||
context 'when nova network' do
|
||||
|
||||
|
||||
context 'when multi-host is not set' do
|
||||
let :params do
|
||||
default_params.merge(:quantum => false, :multi_host => false)
|
||||
end
|
||||
it {should contain_class('nova::network').with(
|
||||
:private_interface => 'eth0',
|
||||
:public_interface => 'eth1',
|
||||
@@ -328,11 +476,11 @@ describe 'openstack::controller' do
|
||||
:enabled => true,
|
||||
:install_service => true
|
||||
)}
|
||||
|
||||
end
|
||||
describe 'when multihost is set' do
|
||||
|
||||
context 'when multi-host is set' do
|
||||
let :params do
|
||||
default_params.merge(:multi_host => true)
|
||||
default_params.merge(:quantum => false, :multi_host => true)
|
||||
end
|
||||
it { should contain_nova_config('multi_host').with(:value => 'True')}
|
||||
it {should contain_class('nova::network').with(
|
||||
@@ -340,46 +488,8 @@ describe 'openstack::controller' do
|
||||
:enabled => false,
|
||||
:install_service => false
|
||||
)}
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'when not enabled' do
|
||||
|
||||
describe 'when multihost is set' do
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:multi_host => true,
|
||||
:enabled => false
|
||||
)
|
||||
end
|
||||
|
||||
it {should contain_class('nova::network').with(
|
||||
:create_networks => false,
|
||||
:enabled => false,
|
||||
:install_service => false
|
||||
)}
|
||||
|
||||
end
|
||||
describe 'when multihost is not set' do
|
||||
let :params do
|
||||
default_params.merge(
|
||||
:multi_host => false,
|
||||
:enabled => false
|
||||
)
|
||||
end
|
||||
|
||||
it {should contain_class('nova::network').with(
|
||||
:create_networks => false,
|
||||
:enabled => false,
|
||||
:install_service => false
|
||||
)}
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
Reference in New Issue
Block a user