Merge "New tasks for Horizon, API-proxy and Ceph radosgw"

This commit is contained in:
Jenkins 2015-03-12 08:39:57 +00:00 committed by Gerrit Code Review
commit 3e810535fa
20 changed files with 524 additions and 43 deletions

View File

@ -11,6 +11,7 @@ class ceph::radosgw (
$rgw_id = 'radosgw.gateway', $rgw_id = 'radosgw.gateway',
$rgw_user = $::ceph::params::user_httpd, $rgw_user = $::ceph::params::user_httpd,
$use_ssl = $::ceph::use_ssl, $use_ssl = $::ceph::use_ssl,
$primary_mon = $::ceph::primary_mon,
# RadosGW settings # RadosGW settings
$rgw_host = $::ceph::rgw_host, $rgw_host = $::ceph::rgw_host,
@ -32,6 +33,9 @@ class ceph::radosgw (
$rgw_keystone_accepted_roles = $::ceph::rgw_keystone_accepted_roles, $rgw_keystone_accepted_roles = $::ceph::rgw_keystone_accepted_roles,
$rgw_keystone_revocation_interval = $::ceph::rgw_keystone_revocation_interval, $rgw_keystone_revocation_interval = $::ceph::rgw_keystone_revocation_interval,
$rgw_nss_db_path = $::ceph::rgw_nss_db_path, $rgw_nss_db_path = $::ceph::rgw_nss_db_path,
$pub_ip = $::ceph::rgw_pub_ip,
$adm_ip = $::ceph::rgw_adm_ip,
$int_ip = $::ceph::rgw_int_ip,
#rgw Log settings #rgw Log settings
$use_syslog = $::ceph::use_syslog, $use_syslog = $::ceph::use_syslog,
@ -90,8 +94,8 @@ class ceph::radosgw (
$httpd_ssl = $::ceph::params::dir_httpd_ssl $httpd_ssl = $::ceph::params::dir_httpd_ssl
exec {'copy OpenSSL certificates': exec {'copy OpenSSL certificates':
command => "scp -r ${rgw_nss_db_path}/* ${::ceph::primary_mon}:${rgw_nss_db_path} && \ command => "scp -r ${rgw_nss_db_path}/* ${primary_mon}:${rgw_nss_db_path} && \
ssh ${::ceph::primary_mon} '/etc/init.d/radosgw restart'", ssh ${primary_mon} '/etc/init.d/radosgw restart'",
} }
exec {"generate SSL certificate on ${name}": exec {"generate SSL certificate on ${name}":
command => "openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${httpd_ssl}apache.key -out ${httpd_ssl}apache.crt -subj '/C=RU/ST=Russia/L=Saratov/O=Mirantis/OU=CA/CN=localhost'", command => "openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${httpd_ssl}apache.key -out ${httpd_ssl}apache.crt -subj '/C=RU/ST=Russia/L=Saratov/O=Mirantis/OU=CA/CN=localhost'",
@ -130,7 +134,12 @@ class ceph::radosgw (
} #END rgw_use_pki } #END rgw_use_pki
class {'ceph::keystone': } class {'ceph::keystone':
pub_ip => $pub_ip,
adm_ip => $adm_ip,
int_ip => $int_ip,
swift_endpoint_port => $swift_endpoint_port,
}
} #END rgw_use_keystone } #END rgw_use_keystone
@ -166,8 +175,8 @@ class ceph::radosgw (
} }
file {[$::ceph::params::dir_httpd_ssl, file {[$::ceph::params::dir_httpd_ssl,
"${::ceph::rgw_data}/ceph-${rgw_id}", "${rgw_data}/ceph-${rgw_id}",
$::ceph::rgw_data, $rgw_data,
$dir_httpd_root, $dir_httpd_root,
$rgw_nss_db_path, $rgw_nss_db_path,
]: ]:
@ -210,8 +219,8 @@ class ceph::radosgw (
"${::ceph::params::dir_httpd_sites}/fastcgi.conf", "${::ceph::params::dir_httpd_sites}/fastcgi.conf",
"${dir_httpd_root}/s3gw.fcgi", "${dir_httpd_root}/s3gw.fcgi",
$::ceph::params::dir_httpd_ssl, $::ceph::params::dir_httpd_ssl,
"${::ceph::rgw_data}/ceph-${rgw_id}", "${rgw_data}/ceph-${rgw_id}",
$::ceph::rgw_data, $rgw_data,
$dir_httpd_root, $dir_httpd_root,
$rgw_nss_db_path, $rgw_nss_db_path,
$rgw_log_file,]] -> $rgw_log_file,]] ->

View File

@ -534,28 +534,6 @@ class openstack::controller (
} }
} }
######## Horizon ########
class { 'openstack::horizon':
secret_key => $secret_key,
cache_server_ip => $cache_server_ip,
package_ensure => $::openstack_version['horizon'],
bind_address => $api_bind_address,
cache_server_port => $cache_server_port,
swift => $swift,
neutron => $network_provider ? {'nova' => false, 'neutron' => true},
horizon_app_links => $horizon_app_links,
keystone_host => $service_endpoint,
use_ssl => $horizon_use_ssl,
verbose => $verbose,
debug => $debug,
use_syslog => $use_syslog,
nova_quota => hiera('nova_quota'),
servername => $public_address,
} ->
class {'osnailyfacter::apache_api_proxy':
master_ip => hiera('master_ip'),
}
####### Disable upstart startup on install ####### ####### Disable upstart startup on install #######
if($::operatingsystem == 'Ubuntu') { if($::operatingsystem == 'Ubuntu') {
tweaks::ubuntu_service_override { 'glance-api': tweaks::ubuntu_service_override { 'glance-api':

View File

@ -104,12 +104,6 @@ class openstack::horizon (
servername => $servername, servername => $servername,
} }
if ($::osfamily == 'Debian'){
# We need these apache modules for rados-gw
apache::mod {'rewrite': }
apache::mod {'fastcgi': }
}
class { "::apache::mod::$mpm_module": class { "::apache::mod::$mpm_module":
startservers => $startservers, startservers => $startservers,
maxclients => $maxclients, maxclients => $maxclients,

View File

@ -0,0 +1,19 @@
# Configure apache and listen ports
class osnailyfacter::apache (
$listen_ports = '80',
) {
define apache_port {
apache::listen { $name: }
apache::namevirtualhost { "*:${name}": }
}
class { '::apache':
mpm_module => false,
default_vhost => false,
purge_configs => false,
servername => $::hostname,
}
apache_port { $listen_ports: }
}

View File

@ -6,7 +6,7 @@ class osnailyfacter::apache_api_proxy(
# Allow connection to the apache for ostf tests # Allow connection to the apache for ostf tests
firewall {'007 tinyproxy': firewall {'007 tinyproxy':
dport => [ 8888 ], dport => [ 8888 ],
source => hiera('master_ip'), source => $master_ip,
proto => 'tcp', proto => 'tcp',
action => 'accept', action => 'accept',
} }

View File

@ -0,0 +1,11 @@
notice('MODULAR: api-proxy.pp')
# Apache and listen ports
class { 'osnailyfacter::apache':
listen_ports => hiera_array('apache_ports', ['80', '8888']),
}
# API proxy vhost
class {'osnailyfacter::apache_api_proxy':
master_ip => hiera('master_ip'),
}

View File

@ -0,0 +1,23 @@
require 'test/unit'
require 'socket'
def test_connection(host, port)
begin
s = TCPSocket.open(host, port)
s.close
rescue
return false
end
true
end
def api_proxy_online?
test_connection('localhost', '8888')
end
class ApiProxyPostTest < Test::Unit::TestCase
def test_api_proxy_online
assert api_proxy_online?, 'Can not connect to API proxy!'
end
end

View File

@ -0,0 +1,11 @@
- id: api-proxy
type: puppet
groups: [primary-controller, controller]
required_for: [deploy_end, controller_remaining_tasks]
requires: [horizon]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/api-proxy/api-proxy.pp
puppet_modules: /etc/puppet/modules
timeout: 3600
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/api-proxy/api-proxy_post.rb

View File

@ -0,0 +1,84 @@
notice('MODULAR: ceph/radosgw.pp')
$storage_hash = hiera('storage', {})
$controllers = hiera('controllers')
$use_neutron = hiera('use_neutron')
$public_vip = hiera('public_vip')
$keystone_hash = hiera('keystone', {})
$management_vip = hiera('management_vip')
if (!empty(filter_nodes(hiera('nodes'), 'role', 'ceph-osd')) or
$storage_hash['volumes_ceph'] or
$storage_hash['images_ceph'] or
$storage_hash['objects_ceph']
) {
$use_ceph = true
} else {
$use_ceph = false
}
if $use_ceph and $storage_hash['objects_ceph'] {
$primary_mons = $controllers
$primary_mon = $controllers[0]['name']
if ($use_neutron) {
prepare_network_config(hiera('network_scheme', {}))
$ceph_cluster_network = get_network_role_property('storage', 'cidr')
$ceph_public_network = get_network_role_property('management', 'cidr')
} else {
$ceph_cluster_network = hiera('storage_network_range')
$ceph_public_network = hiera('management_network_range')
}
# Apache and listen ports
class { 'osnailyfacter::apache':
listen_ports => hiera_array('apache_ports', ['80', '8888']),
}
if ($::osfamily == 'Debian'){
apache::mod {'rewrite': }
apache::mod {'fastcgi': }
}
include ceph::params
class { 'ceph::radosgw':
# SSL
use_ssl => false,
# Ceph
primary_mon => $primary_mon,
pub_ip => $public_vip,
adm_ip => $management_vip,
int_ip => $management_vip,
# RadosGW settings
rgw_host => $::hostname,
rgw_port => '6780',
swift_endpoint_port => '8080',
rgw_keyring_path => '/etc/ceph/keyring.radosgw.gateway',
rgw_socket_path => '/tmp/radosgw.sock',
rgw_log_file => '/var/log/ceph/radosgw.log',
rgw_data => '/var/lib/ceph/radosgw',
rgw_dns_name => "*.${::domain}",
rgw_print_continue => true,
#rgw Keystone settings
rgw_use_pki => false,
rgw_use_keystone => true,
rgw_keystone_url => "${public_vip}:5000",
rgw_keystone_admin_token => $keystone_hash['admin_token'],
rgw_keystone_token_cache_size => '10',
rgw_keystone_accepted_roles => '_member_, Member, admin, swiftoperator',
rgw_keystone_revocation_interval => '1000000',
rgw_nss_db_path => '/etc/ceph/nss',
#rgw Log settings
use_syslog => hiera('use_syslog', true),
syslog_facility => hiera('syslog_log_facility_ceph', 'LOG_LOCAL0'),
syslog_level => hiera('syslog_log_level_ceph', 'info'),
}
Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ],
cwd => '/root',
}
}

View File

@ -0,0 +1,71 @@
require 'test/unit'
require 'socket'
def process_tree
return $process_tree if $process_tree
$process_tree = {}
ps = `ps haxo pid,ppid,cmd`
ps.split("\n").each do |p|
f = p.split
pid = f.shift.to_i
ppid = f.shift.to_i
cmd = f.join ' '
# create entry for this pid if not present
$process_tree[pid] = {
:children => []
} unless $process_tree.key? pid
# fill this entry
$process_tree[pid][:ppid] = ppid
$process_tree[pid][:pid] = pid
$process_tree[pid][:cmd] = cmd
unless ppid == 0
# create entry for parent process if not present
$process_tree[ppid] = {
:children => [],
:cmd => '',
} unless $process_tree.key? ppid
# fill parent's children
$process_tree[ppid][:children] << pid
end
end
$process_tree
end
def test_connection(host, port)
begin
s = TCPSocket.open(host, port)
s.close
rescue
return false
end
true
end
def radosgw_backend_online?
test_connection('localhost', '6780')
end
PROCESSES = %w(
radosgw
)
class RadosgwPostTest < Test::Unit::TestCase
def self.create_tests
PROCESSES.each do |process|
method_name = "test_iprocess_#{process}_running"
define_method method_name do
assert process_tree.find { |pid, proc| proc[:cmd].include? process }, "Process '#{process}' is not running!"
end
end
end
def test_radosgw_backend_online
assert radosgw_backend_online?, 'Can not connect to radoswg on this host!'
end
end
RadosgwPostTest.create_tests

View File

@ -0,0 +1,63 @@
require 'hiera'
require 'test/unit'
require 'open-uri'
require 'socket'
def hiera
return $hiera if $hiera
$hiera = Hiera.new(:config => '/etc/puppet/hiera.yaml')
end
def management_vip
return $management_vip if $management_vip
$management_vip = hiera.lookup 'management_vip', nil, {}
end
def hostname
return $hostname if $hostname
$hostname = Socket.gethostname.split('.').first
end
def controller_node_address
return $controller_node_address if $controller_node_address
$controller_node_address = hiera.lookup 'controller_node_address', nil, {}
end
def haproxy_stats_url
ip = management_vip
ip = controller_node_address unless ip
raise 'Could not get internal address!' unless ip
port = 10000
"http://#{ip}:#{port}/;csv"
end
def csv
return $csv if $csv
begin
url = open(haproxy_stats_url)
csv = url.read
rescue
nil
end
return nil unless csv and not csv.empty?
$csv = csv
end
def keystone_backends_online?
raise 'Could not get CSV from HAProxy stats!' unless csv
status = false
csv.split("\n").each do |line|
next unless line.start_with? 'keystone-1'
next unless line.include? 'BACKEND'
puts "DEBUG: #{line}"
fields = line.split(',')
status ||= fields[17].eql? 'UP'
end
status
end
class RadosgwPreTest < Test::Unit::TestCase
def test_keystone_backends_are_online
assert keystone_backends_online?, 'Haproxy keystone backend is down!'
end
end

View File

@ -0,0 +1,13 @@
- id: ceph-radosgw
type: puppet
groups: [primary-controller, controller]
required_for: [deploy_end, controller_remaining_tasks]
requires: [horizon]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/ceph/radosgw.pp
puppet_modules: /etc/puppet/modules
timeout: 3600
test_pre:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/ceph/radosgw_pre.rb
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/ceph/radosgw_post.rb

View File

@ -54,6 +54,7 @@ $syslog_log_facility_ceph = hiera('syslog_log_facility_ceph','LOG_LOCAL0')
$nova_report_interval = hiera('nova_report_interval', 60) $nova_report_interval = hiera('nova_report_interval', 60)
$nova_service_down_time = hiera('nova_service_down_time', 180) $nova_service_down_time = hiera('nova_service_down_time', 180)
$apache_ports = hiera_array('apache_ports', ['80', '8888'])
$openstack_version = hiera('openstack_version', $openstack_version = hiera('openstack_version',
{ {

View File

@ -0,0 +1,22 @@
notice('MODULAR: horizon.pp')
$controllers = hiera('controllers')
$controller_internal_addresses = nodes_to_hash($controllers,'name','internal_address')
$controller_nodes = ipsort(values($controller_internal_addresses))
class { 'openstack::horizon':
secret_key => hiera('secret_key', 'dummy_secret_key'),
cache_server_ip => $controller_nodes,
package_ensure => hiera('horizon_package_ensure', 'installed'),
bind_address => hiera('internal_address'),
cache_server_port => '11211',
neutron => hiera('use_neutron'),
keystone_host => hiera('management_vip'),
use_ssl => hiera('horizon_use_ssl', false),
verbose => hiera('verbose', true),
debug => hiera('debug'),
use_syslog => hiera('use_syslog', true),
nova_quota => hiera('nova_quota'),
servername => hiera('public_vip'),
}

View File

@ -0,0 +1,64 @@
require 'hiera'
require 'test/unit'
require 'open-uri'
require 'socket'
def hiera
return $hiera if $hiera
$hiera = Hiera.new(:config => '/etc/puppet/hiera.yaml')
end
def management_vip
return $management_vip if $management_vip
$management_vip = hiera.lookup 'management_vip', nil, {}
end
def hostname
return $hostname if $hostname
$hostname = Socket.gethostname.split('.').first
end
def controller_node_address
return $controller_node_address if $controller_node_address
$controller_node_address = hiera.lookup 'controller_node_address', nil, {}
end
def haproxy_stats_url
ip = management_vip
ip = controller_node_address unless ip
raise 'Could not get internal address!' unless ip
port = 10000
"http://#{ip}:#{port}/;csv"
end
def csv
return $csv if $csv
begin
url = open(haproxy_stats_url)
csv = url.read
rescue
nil
end
return nil unless csv and not csv.empty?
$csv = csv
end
def horizon_backend_online?
raise 'Could not get CSV from HAProxy stats!' unless csv
status = 'DOWN'
csv.split("\n").each do |line|
next unless line.start_with? 'horizon'
next unless line.include? hostname
puts "DEBUG: #{line}"
fields = line.split(',')
status = fields[17]
end
status == 'UP'
end
class HorizonPostTest < Test::Unit::TestCase
def test_horizon_backend_online
assert horizon_backend_online?, 'Haproxy horizon backend is down on this node!'
end
end

View File

@ -0,0 +1,104 @@
require 'hiera'
require 'test/unit'
require 'open-uri'
require 'socket'
def hiera
return $hiera if $hiera
$hiera = Hiera.new(:config => '/etc/puppet/hiera.yaml')
end
def management_vip
return $management_vip if $management_vip
$management_vip = hiera.lookup 'management_vip', nil, {}
end
def hostname
return $hostname if $hostname
$hostname = Socket.gethostname.split('.').first
end
def controller_node_address
return $controller_node_address if $controller_node_address
$controller_node_address = hiera.lookup 'controller_node_address', nil, {}
end
def process_tree
return $process_tree if $process_tree
$process_tree = {}
ps = `ps haxo pid,ppid,cmd`
ps.split("\n").each do |p|
f = p.split
pid = f.shift.to_i
ppid = f.shift.to_i
cmd = f.join ' '
# create entry for this pid if not present
$process_tree[pid] = {
:children => []
} unless $process_tree.key? pid
# fill this entry
$process_tree[pid][:ppid] = ppid
$process_tree[pid][:pid] = pid
$process_tree[pid][:cmd] = cmd
unless ppid == 0
# create entry for parent process if not present
$process_tree[ppid] = {
:children => [],
:cmd => '',
} unless $process_tree.key? ppid
# fill parent's children
$process_tree[ppid][:children] << pid
end
end
$process_tree
end
def haproxy_stats_url
ip = management_vip
ip = controller_node_address unless ip
raise 'Could not get internal address!' unless ip
port = 10000
"http://#{ip}:#{port}/;csv"
end
def csv
return $csv if $csv
begin
url = open(haproxy_stats_url)
csv = url.read
rescue
nil
end
return nil unless csv and not csv.empty?
$csv = csv
end
def is_memcached_accessible?
# TODO: write test to check connectivity to memcached port on localhost
true
end
PROCESSES = %w(
memcached
)
class HorizonPreTest < Test::Unit::TestCase
def self.create_tests
PROCESSES.each do |process|
method_name = "test_iprocess_#{process}_running"
define_method method_name do
assert process_tree.find { |pid, proc| proc[:cmd].include? process }, "Process '#{process}' is not running!"
end
end
end
def test_memcached_is_accessible
assert is_memcached_accessible?, 'Memcached is not accessible!'
end
end
HorizonPreTest.create_tests

View File

@ -0,0 +1,13 @@
- id: horizon
type: puppet
groups: [primary-controller, controller]
required_for: [deploy_end]
requires: [openstack-controller]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/horizon/horizon.pp
puppet_modules: /etc/puppet/modules
timeout: 3600
test_pre:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/horizon/horizon_pre.rb
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/horizon/horizon_post.rb

View File

@ -192,7 +192,7 @@ if $use_ceph {
osd_pool_default_size => $storage_hash['osd_pool_size'], osd_pool_default_size => $storage_hash['osd_pool_size'],
osd_pool_default_pg_num => $storage_hash['pg_num'], osd_pool_default_pg_num => $storage_hash['pg_num'],
osd_pool_default_pgp_num => $storage_hash['pg_num'], osd_pool_default_pgp_num => $storage_hash['pg_num'],
use_rgw => $storage_hash['objects_ceph'], use_rgw => false, # we configure rados-gw in a separate task
glance_backend => $glance_backend, glance_backend => $glance_backend,
rgw_pub_ip => $public_vip, rgw_pub_ip => $public_vip,
rgw_adm_ip => $management_vip, rgw_adm_ip => $management_vip,

View File

@ -4,10 +4,10 @@
HostnameLookups off HostnameLookups off
<Proxy *> <Proxy *>
Order Deny,Allow Order Deny,Allow
<% if master_ip.kind_of?(Array) -%> <% if @master_ip.kind_of?(Array) -%>
Allow from <%= master_ip.join(",") %> Allow from <%= @master_ip.join(",") %>
<% else -%> <% else -%>
Allow from <%= master_ip %> Allow from <%= @master_ip %>
<% end -%> <% end -%>
Deny from all Deny from all
</Proxy> </Proxy>

View File

@ -3,6 +3,7 @@
<% globals.store "access_hash", @access_hash -%> <% globals.store "access_hash", @access_hash -%>
<% globals.store "amqp_hosts", @amqp_hosts -%> <% globals.store "amqp_hosts", @amqp_hosts -%>
<% globals.store "amqp_port", @amqp_port -%> <% globals.store "amqp_port", @amqp_port -%>
<% globals.store "apache_ports", @apache_ports -%>
<% globals.store "base_mac", @base_mac -%> <% globals.store "base_mac", @base_mac -%>
<% globals.store "base_syslog_hash", @base_syslog_hash -%> <% globals.store "base_syslog_hash", @base_syslog_hash -%>
<% globals.store "ceilometer_hash", @ceilometer_hash -%> <% globals.store "ceilometer_hash", @ceilometer_hash -%>