From 2fef9647e6161765715a1151c01612e521f6de08 Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Wed, 9 Oct 2013 16:42:32 +0200 Subject: [PATCH] Add manifest files Signed-off-by: Emilien Macchi --- classes/authorized_keys.pp | 48 ++++ params.pp | 0 roles/common/rabbitmq.pp | 55 ++++ roles/identity/keystone.pp | 253 ++++++++++++++++++ roles/metering/ceilometer.pp | 37 +++ roles/metering/common_ceilometer.pp | 38 +++ roles/object-storage/common_swift.pp | 99 +++++++ roles/object-storage/swift_proxy.pp | 104 +++++++ roles/object-storage/swift_ringbuiler.pp | 77 ++++++ roles/object-storage/swift_storage.pp | 132 +++++++++ site.pp | 0 templates/check_galera_cluster | 15 ++ templates/check_swift_recon | 123 +++++++++ templates/clustercheck | 36 +++ templates/munin/munin-node.conf.Ubuntu | 54 ++++ .../munin/munin-node.conf.Ubuntu.precise | 54 ++++ templates/mysqlchk | 18 ++ 17 files changed, 1143 insertions(+) create mode 100644 classes/authorized_keys.pp create mode 100644 params.pp create mode 100644 roles/common/rabbitmq.pp create mode 100644 roles/identity/keystone.pp create mode 100644 roles/metering/ceilometer.pp create mode 100644 roles/metering/common_ceilometer.pp create mode 100644 roles/object-storage/common_swift.pp create mode 100644 roles/object-storage/swift_proxy.pp create mode 100644 roles/object-storage/swift_ringbuiler.pp create mode 100644 roles/object-storage/swift_storage.pp create mode 100644 site.pp create mode 100644 templates/check_galera_cluster create mode 100755 templates/check_swift_recon create mode 100755 templates/clustercheck create mode 100644 templates/munin/munin-node.conf.Ubuntu create mode 100644 templates/munin/munin-node.conf.Ubuntu.precise create mode 100644 templates/mysqlchk diff --git a/classes/authorized_keys.pp b/classes/authorized_keys.pp new file mode 100644 index 00000000..8001e026 --- /dev/null +++ b/classes/authorized_keys.pp @@ -0,0 +1,48 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# SSH authorized_keys + +class authorized_keys ($keys, $account='root', $home = '') { + # This line allows default homedir based on $account variable. + # If $home is empty, the default is used. + $rhome = $account ? {'root' => "/root", default => $home} + $homedir = $rhome ? {'' => "/home/${account}", default => $rhome} + file { "${homedir}/.ssh": + ensure => directory, + owner => $ensure ? {'present' => $account, default => undef }, + group => $ensure ? {'present' => $account, default => undef }, + mode => 755, + } + file { "${homedir}/.ssh/authorized_keys": + owner => $ensure ? {'present' => $account, default => undef }, + group => $ensure ? {'present' => $account, default => undef }, + mode => 644, + require => File["${homedir}/.ssh"], + } + + define addkey{ + exec{"key-$name": + command => "/bin/echo '${name}' >> ${homedir}/.ssh/authorized_keys", + unless => "/bin/grep -xFq '${name}' ${homedir}/.ssh/authorized_keys", + require => File["${homedir}/.ssh/authorized_keys"], + } + } + addkey{$keys:;} +} diff --git a/params.pp b/params.pp new file mode 100644 index 00000000..e69de29b diff --git a/roles/common/rabbitmq.pp b/roles/common/rabbitmq.pp new file mode 100644 index 00000000..1c55d170 --- /dev/null +++ b/roles/common/rabbitmq.pp @@ -0,0 +1,55 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# RabbitMQ node + +class os_role_rabbitmq{ + class { 'rabbitmq::server': + delete_guest_user => true, + config_cluster => true, + cluster_disk_nodes => $os_params::rabbit_names, + wipe_db_on_cookie_change => true, + } + + rabbitmq_vhost { '/': + provider => 'rabbitmqctl', + require => Class['rabbitmq::server'], + } + rabbitmq_user { ['nova','glance', 'quantum', 'cinder', 'ceilometer', 'heat', 'sensu']: + admin => true, + password => $os_params::rabbit_password, + provider => 'rabbitmqctl', + require => Class['rabbitmq::server'] + } + rabbitmq_user_permissions {[ + 'nova@/', + 'glance@/', + 'quantum@/', + 'cinder@/', + 'ceilometer@/', + 'heat@/', + 'sensu@/', + ]: + configure_permission => '.*', + write_permission => '.*', + read_permission => '.*', + provider => 'rabbitmqctl', + } + +} diff --git a/roles/identity/keystone.pp b/roles/identity/keystone.pp new file mode 100644 index 00000000..54abff04 --- /dev/null +++ b/roles/identity/keystone.pp @@ -0,0 +1,253 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class os_role_keystone ( + $local_ip = $ipaddress_eth1, +){ + + $encoded_user = uriescape($os_params::keystone_db_user) + $encoded_password = uriescape($os_params::keystone_db_password) + +# Running Keystone service with WSGI and Apache2 + class {'apache': + default_vhost => false + } + + class { 'keystone::wsgi::apache': + port => 8082 + } + + apache::vhost { 'keystone_main_proxy': + servername => $::fqdn, + port => 5000, + docroot => $::keystone::params::keystone_wsgi_script_path, + docroot_owner => 'keystone', + docroot_group => 'keystone', + error_log_file => "${::fqdn}_main_error.log", + access_log_file => "${::fqdn}_main_access.log", + configure_firewall => false, + custom_fragment => inline_template(' +WSGIScriptAlias / /usr/lib/cgi-bin/keystone/main +WSGIProcessGroup keystone +') + } + + apache::vhost { 'keystone_admin_proxy': + servername => $::fqdn, + port => 35357, + docroot => $::keystone::params::keystone_wsgi_script_path, + docroot_owner => 'keystone', + docroot_group => 'keystone', + error_log_file => "${::fqdn}_admin_error.log", + access_log_file => "${::fqdn}_admin_access.log", + configure_firewall => false, + custom_fragment => inline_template(' +WSGIScriptAlias / /usr/lib/cgi-bin/keystone/admin +WSGIProcessGroup keystone +') + } + +# Configure Keystone + class { 'keystone': + enabled => false, + package_ensure => 'latest', + admin_token => $os_params::ks_admin_token, + compute_port => "8774", + verbose => false, + debug => false, + sql_connection => "mysql://${encoded_user}:${encoded_password}@${os_params::keystone_db_host}/keystone", + idle_timeout => 60, +# ToDo (EmilienM): Update to PKI tokens + token_format => "UUID", + } + + keystone_config { + "token/driver": value => "keystone.token.backends.memcache.Token"; + "token/expiration": value => "86400"; + "memcache/servers": value => inline_template("<%= scope.lookupvar('os_params::keystone_memchached').join(',') %>"); + "ec2/driver": value => "keystone.contrib.ec2.backends.sql.Ec2"; + "DEFAULT/syslog_log_facility": value => 'LOG_LOCAL0'; + "DEFAULT/use_syslog": value => 'yes'; + } + +# Configure Load Balancers + @@haproxy::balancermember{"${fqdn}-keystone": + listening_service => "keystone_cluster", + server_names => $::hostname, + ipaddresses => $local_ip, + ports => $os_params::keystone_port, + options => "check inter 2000 rise 2 fall 5" + } + + @@haproxy::balancermember{"${fqdn}-keystone-admin": + listening_service => "keystone_admin_cluster", + server_names => $::hostname, + ipaddresses => $local_ip, + ports => $os_params::keystone_admin_port, + options => "check inter 2000 rise 2 fall 5" + } + + +# Keystone Endpoints + Users + class { 'keystone::roles::admin': + email => $os_params::ks_admin_email, + password => $os_params::ks_admin_password, + } + + keystone_role { $os_params::keystone_roles_addons: ensure => present } + + class {"keystone::endpoint": + public_address => $os_params::ks_keystone_public_host, + admin_address => $os_params::ks_keystone_admin_host, + internal_address => $os_params::ks_keystone_internal_host, + public_port => $os_params::ks_keystone_public_port, + admin_port => $os_params::keystone_admin_port, + internal_port => $os_params::keystone_port, + region => 'RegionOne', + public_protocol => $os_params::ks_keystone_public_proto + } + + class{"swift::keystone::auth": + password => $os_params::ks_swift_password, + address => $os_params::ks_swift_internal_host, + port => $os_params::swift_port, + public_address => $os_params::ks_swift_public_host, + public_protocol => $os_params::ks_swift_public_proto, + public_port => $os_params::ks_swift_public_port + } + + class { 'nova::keystone::auth': + password => $os_params::ks_nova_password, + public_address => $os_params::ks_nova_public_host, + admin_address => $os_params::ks_nova_admin_host, + internal_address => $os_params::ks_nova_internal_host, + public_protocol => $os_params::ks_nova_public_proto, + cinder => true, + } + + class { 'cinder::keystone::auth': + password => $os_params::ks_cinder_password, + public_address => $os_params::ks_cinder_public_host, + admin_address => $os_params::ks_cinder_admin_host, + internal_address => $os_params::ks_cinder_internal_host, + public_protocol => $os_params::ks_cinder_public_proto, + } + + class { 'glance::keystone::auth': + password => $os_params::ks_glance_password, + public_address => $os_params::ks_glance_public_host, + admin_address => $os_params::ks_glance_admin_host, + internal_address => $os_params::ks_glance_internal_host, + public_protocol => $os_params::ks_glance_public_proto, + } + + class { 'quantum::keystone::auth': + password => $os_params::ks_quantum_password, + public_address => $os_params::ks_quantum_public_host, + admin_address => $os_params::ks_quantum_admin_host, + internal_address => $os_params::ks_quantum_internal_host, + public_protocol => $os_params::ks_quantum_public_proto, + port => $os_params::quantum_port, + } + + class { 'ceilometer::keystone::auth': + password => $os_params::ks_ceilometer_password, + public_address => $os_params::ks_ceilometer_public_host, + admin_address => $os_params::ks_ceilometer_admin_host, + internal_address => $os_params::ks_ceilometer_internal_host, + public_protocol => $os_params::ks_ceilometer_public_proto, + port => $os_params::ceilometer_port, + } + +# Note for Midonet: endpoint is created manually since +# there is no Puppet module. + + keystone_tenant { $os_params::glance_swift_tenant: + ensure => present, + enabled => 'True', + description => 'glance images tenant' + } -> + keystone_user { $os_params::glance_swift_user: + ensure => present, + email => "${os_params::glance_swift_user}@localhost", + password => $os_params::glance_swift_password, + tenant => $os_params::glance_swift_tenant + } -> + keystone_user_role { "${os_params::glance_swift_user}@${os_params::glance_swift_tenant}": + ensure => present, + roles => 'admin' + } + + keystone_tenant { $os_params::ks_monitoring_tenant: + ensure => present, + enabled => 'True', + description => 'Monitoring Tenant' + } -> + keystone_user { $os_params::ks_monitoring_user: + ensure => present, + email => "${os_params::ks_monitoring_user}@localhost", + password => $os_params::ks_monitoring_password, + tenant => $os_params::ks_monitoring_tenant + } -> + keystone_user_role { "${os_params::ks_monitoring_user}@${os_params::ks_monitoring_tenant}": + ensure => present, + roles => 'admin' + } + +# Specific to Midonet +# keystone_tenant { $os_params::ks_midonet_tenant: +# ensure => present, +# enabled => 'True', +# description => 'Midonet Tenant' +# } -> +# keystone_user { $os_params::ks_midonet_username: +# ensure => present, +# email => "${os_params::ks_midonet_tenant}@localhost", +# password => $os_params::ks_midonet_password, +# tenant => $os_params::ks_midonet_tenant +# } -> +# keystone_user_role { "${os_params::ks_midonet_user}@${os_params::ks_midonet_tenant}": +# ensure => present, +# roles => ${os_params::ks_midonet_role} +# } + + class{ 'swift::keystone::dispersion': + auth_pass => $os_params::ks_swift_dispersion_password + } + +# Waiting apache is configured before using keystone (because of WSGI) + Service['httpd'] -> Keystone_tenant <| |> + Service['httpd'] -> Keystone_user <| |> + Service['httpd'] -> Keystone_role <| |> + Service['httpd'] -> Keystone_service <| |> + Service['httpd'] -> Keystone_user_role <| |> + Service['httpd'] -> Keystone_endpoint <| |> + + +# Due to Keystone WSGI, db need to be sync manually + exec { 'keystone-manage db_sync': + path => '/usr/bin', + user => 'keystone', + refreshonly => true, + notify => Service['keystone'], + subscribe => Package['keystone'], + require => User['keystone'], + } + +} diff --git a/roles/metering/ceilometer.pp b/roles/metering/ceilometer.pp new file mode 100644 index 00000000..6ce3af06 --- /dev/null +++ b/roles/metering/ceilometer.pp @@ -0,0 +1,37 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# Ceilometer nodes + +class os_ceilometer{ + class { 'mongodb': + enable_10gen => true, + } + + class { 'ceilometer::db': + database_connection => $os_params::ceilometer_database_connection, + require => Class['mongodb'] + } + + class { 'ceilometer::collector': } + +# Ceilometer Central Agent is defined in site.pp since it must be installed on only node (not able to scale-out) + +} + diff --git a/roles/metering/common_ceilometer.pp b/roles/metering/common_ceilometer.pp new file mode 100644 index 00000000..1f0e1c93 --- /dev/null +++ b/roles/metering/common_ceilometer.pp @@ -0,0 +1,38 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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 by Controller & Compute nodes + +class ceilometer_common { + class { 'ceilometer': + metering_secret => $os_params::ceilometer_secret, + rabbit_hosts => $os_params::rabbit_hosts, + rabbit_password => $os_params::rabbit_password, + rabbit_userid => 'ceilometer', + verbose => false, + debug => false, + } + + ceilometer_config { + 'DEFAULT/syslog_log_facility': value => 'LOG_LOCAL0'; + 'DEFAULT/use_syslog': value => 'yes'; + } + +} diff --git a/roles/object-storage/common_swift.pp b/roles/object-storage/common_swift.pp new file mode 100644 index 00000000..441220ea --- /dev/null +++ b/roles/object-storage/common_swift.pp @@ -0,0 +1,99 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# Swift nodes + +class os_role_swift { + + class { 'ssh::server::install': } + + class { 'swift': + swift_hash_suffix => $os_params::swift_hash_suffix, + package_ensure => latest, + } + class {"os_swift_system::tweaking": } +} + +class os_swift_system::tweaking { + file {"/etc/sysctl.d/swift-tuning.conf": + content => " +# disable TIME_WAIT.. wait.. +net.ipv4.tcp_tw_recycle=1 +net.ipv4.tcp_tw_reuse=1 + +# disable syn cookies +net.ipv4.tcp_syncookies = 0 + +# double amount of allowed conntrack +net.ipv4.netfilter.ip_conntrack_max = 524288 +net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 2 +net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 2 + +net.ipv4.ip_local_port_range = 1024 65000 + +## 10Gb Tuning +net.core.netdev_max_backlog = 300000 +net.ipv4.tcp_timestamps = 0 +net.ipv4.tcp_sack = 0 + +", + owner => "root", + group => "root", + } + + exec{"update-etc-modules-with-ip_conntrack": + command => "/bin/echo ip_conntrack >> /etc/modules", + unless => "/bin/grep -qFx 'ip_conntrack' /etc/modules", + } + + # Load sysctl and module only the first time + exec{"load-ip_conntrack": + command => "/sbin/modprobe ip_conntrack", + unless => "/bin/grep -qFx 'ip_conntrack' /etc/modules", + require => File['/etc/sysctl.d/swift-tuning.conf'] + } + exec{"reload-sysctl-swift-tunning": + command => "/sbin/sysctl -p /etc/sysctl.d/swift-tuning.conf", + unless => "/bin/grep -qFx 'ip_conntrack' /etc/modules", + require => File['/etc/sysctl.d/swift-tuning.conf'] + } + + file{"/var/log/swift": + ensure => directory, + owner => swift, + group => swift, + } + + file{"/etc/logrotate.d/swift": + content => " + /var/log/swift/proxy.log /var/log/swift/proxy.error.log /var/log/swift/account-server.log /var/log/swift/account-server.error.log /var/log/swift/container-server.log /var/log/swift/container-server.error.log /var/log/swift/object-server.log /var/log/swift/object-server.error.log +{ + rotate 7 + daily + missingok + notifempty + delaycompress + compress + postrotate + endscript +} +" + } + +} diff --git a/roles/object-storage/swift_proxy.pp b/roles/object-storage/swift_proxy.pp new file mode 100644 index 00000000..149e3012 --- /dev/null +++ b/roles/object-storage/swift_proxy.pp @@ -0,0 +1,104 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# Swift Proxy node + +class os_role_swift_proxy( + $local_ip = $ipaddress_eth1, +) inherits os_role_swift { + + class { 'memcached': + listen_ip => $local_ip, + max_memory => '60%', + } + + class { 'swift::proxy': + proxy_local_net_ip => $local_ip, + port => $os_params::swift_port, + pipeline => [ + 'catch_errors', 'healthcheck', 'cache', 'ratelimit', + 'swift3', 's3token', 'tempurl', 'formpost', 'authtoken', + 'keystone', 'proxy-logging', 'proxy-server'], + account_autocreate => true, + log_level => 'DEBUG', + workers => inline_template('<%= processorcount.to_i * 2 %> +cors_allow_origin = <%= scope.lookupvar("os_params::swift_cors_allow_origin") %> +log_statsd_host = <%= scope.lookupvar("os_params::statsd_host") %> +log_statsd_port = <%= scope.lookupvar("os_params::statsd_port") %> +log_statsd_default_sample_rate = 1 +'), + } + class{'swift::proxy::cache': + memcache_servers => inline_template( + '<%= scope.lookupvar("os_params::swift_memchached").join(",") %>'), + } + + class { 'swift::proxy::proxy-logging': } + class { 'swift::proxy::healthcheck': } + class { 'swift::proxy::catch_errors': } + class { 'swift::proxy::ratelimit': } + + class { 'swift::proxy::keystone': + operator_roles => ['admin', 'SwiftOperator', 'ResellerAdmin'], + } + + class { 'swift::proxy::tempurl': } + class { 'swift::proxy::formpost': } + class { 'swift::proxy::authtoken': + admin_password => $os_params::ks_swift_password, + auth_host => $os_params::ks_keystone_admin_host, + auth_port => $os_params::keystone_admin_port, + delay_auth_decision => inline_template('1 +cache = swift.cache') + } + + class { 'swift::proxy::swift3': + ensure => 'latest', + } + class { 'swift::proxy::s3token': + auth_host => $os_params::ks_keystone_admin_host, + auth_port => $os_params::keystone_admin_port, + } + + class { 'swift::dispersion': + auth_url => "http://${os_params::ks_keystone_internal_host}:${os_params::keystone_port}/v2.0 +endpoint_type=internalURL", + auth_pass => $os_params::ks_swift_dispersion_password + } + + #Note(sileht): log file should exists to swift proxy to write to + # the ceilometer directory + file{"/var/log/ceilometer/swift-proxy-server.log": + ensure => present, + owner => 'swift', + group => 'swift', + notify => Service['swift-proxy'] + } + + @@haproxy::balancermember{"${::fqdn}-swift": + listening_service => 'swift_cluster', + server_names => $::hostname, + ipaddresses => $local_ip, + ports => $os_params::swift_port, + options => 'check inter 2000 rise 2 fall 5' + } + + Swift::Ringsync<<| |>> #~> Service["swift-proxy"] + +} diff --git a/roles/object-storage/swift_ringbuiler.pp b/roles/object-storage/swift_ringbuiler.pp new file mode 100644 index 00000000..5371377a --- /dev/null +++ b/roles/object-storage/swift_ringbuiler.pp @@ -0,0 +1,77 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# Swift ring builder node + + +class os_role_swift_ringbuilder( + $rsyncd_ipaddress = ipaddress_eth1, + $replicas = 3 +) inherits os_role_swift { + + Ring_object_device <<| |>> + Ring_container_device <<| |>> + Ring_account_device <<| |>> + + Class['swift'] -> Class['os_role_swift_ringbuilder'] + + swift::ringbuilder::create{ ['account', 'container']: + part_power => 9, + replicas => $replicas, + min_part_hours => 24, + } + + swift::ringbuilder::create{'object': + part_power => 15, + replicas => $replicas, + min_part_hours => 24, + } + + Swift::Ringbuilder::Create['object'] -> Ring_object_device <| |> ~> Swift::Ringbuilder::Rebalance['object'] + Swift::Ringbuilder::Create['container'] -> Ring_container_device <| |> ~> Swift::Ringbuilder::Rebalance['container'] + Swift::Ringbuilder::Create['account'] -> Ring_account_device <| |> ~> Swift::Ringbuilder::Rebalance['account'] + + swift::ringbuilder::rebalance{ ['object', 'account', 'container']: } + + class { 'rsync::server': + use_xinetd => true, + address => $rsyncd_ipaddress, + use_chroot => 'no', + } + + Rsync::Server::Module { + incoming_chmod => 'u=rwX,go=rX', + outgoing_chmod => 'u=rwX,go=rX', + } + + rsync::server::module { "swift_server": + path => '/etc/swift', + lock_file => "/var/lock/swift_server.lock", + uid => 'swift', + gid => 'swift', + max_connections => $os_params::swift_rsync_max_connections, + read_only => true, + } + + # exports rsync gets that can be used to sync the ring files + @@swift::ringsync { ['account', 'object', 'container']: + ring_server => $rsyncd_ipaddress, + } +} + diff --git a/roles/object-storage/swift_storage.pp b/roles/object-storage/swift_storage.pp new file mode 100644 index 00000000..717ff6eb --- /dev/null +++ b/roles/object-storage/swift_storage.pp @@ -0,0 +1,132 @@ +# +# Copyright (C) 2013 eNovance SAS +# +# Authors: Mehdi Abaakouk +# Emilien Macchi +# Francois Charlier +# +# 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. + +# Swift Storage node + + +define set_io_scheduler(){ + # TODO: Add it on server boot + exec{"/bin/echo deadline > /sys/block/${name}/queue/scheduler": + onlyif => [ + "/usr/bin/test '-e /sys/block/${name}/queue/scheduler'", + "/bin/grep -v '\[deadline\]' /sys/block/${name}/queue/scheduler" + ], + } +} + + +class os_role_swift_storage ( + $local_ip = $ipaddress_eth1, + $swift_zone = undef, + $object_port = '6000', + $container_port = '6001', + $account_port = '6002', + $onloopdevices = false, +) inherits os_role_swift { + + class { 'swift::storage': + storage_local_net_ip => $local_ip, + } + + Rsync::Server::Module { + incoming_chmod => 'u=rwX,go=rX', + outgoing_chmod => 'u=rwX,go=rX', + } + + Swift::Storage::Server { + #devices => $devices, + storage_local_net_ip => $local_ip, + workers => inline_template('<%= processorcount.to_i / 2 %>'), + replicator_concurrency => 2, + updater_concurrency => 1, + reaper_concurrency => 1, + require => Class['swift'], + mount_check => true, + } + # concurrency at 2 and 1 seems better see + # http://docs.openstack.org/trunk/openstack-object-storage/admin/content/general-service-tuning.html + + swift::storage::server { $account_port: + type => 'account', + config_file_path => 'account-server.conf', + pipeline => ['healthcheck', 'account-server'], + log_facility => 'LOG_LOCAL2', + } + + swift::storage::server { $container_port: + type => 'container', + config_file_path => 'container-server.conf', + workers => inline_template("<%= processorcount.to_i / 2 %> +db_preallocation = on +allow_versions = on +"), # great hack :( + pipeline => ['healthcheck', 'container-server'], + log_facility => 'LOG_LOCAL4', + } + + swift::storage::server { $object_port: + type => 'object', + config_file_path => 'object-server.conf', + pipeline => ['healthcheck', 'recon', 'object-server'], + log_facility => 'LOG_LOCAL6', + } + + swift::storage::filter::recon { 'object': } + swift::storage::filter::healthcheck { 'object': } + swift::storage::filter::healthcheck { 'container': } + swift::storage::filter::healthcheck { 'account': } + + if $onloopdevices { + $object_nodes = flatten([ range('sdd','sdf')]) + swift::storage::loopback{$object_nodes: seek => 10024000 } + swift::storage::loopback{['sdb', 'sdc']: seek => 10024000 } + } else { + $object_nodes = flatten([ range('sda','sdc')]) + swift::storage::xfs { $object_nodes: } + swift::storage::xfs { ['sde', 'sdf']: } + set_io_scheduler{['sde', 'sdf']:} + set_io_scheduler{$object_nodes:} + } + + @@ring_container_device { "${local_ip}:${container_port}/sde": + zone => $swift_zone, + weight => '100.0', + } + @@ring_account_device { "${local_ip}:${account_port}/sdf": + zone => $swift_zone, + weight => '100.0', + } + $object_urls = prefix($object_nodes, "${local_ip}:${object_port}/") + @@ring_object_device {$object_urls: + zone => $swift_zone, + weight => '100.0', + } + + class{[ + 'swift::storage::object', + 'swift::storage::container', + 'swift::storage::account']: + } + + Swift::Ringsync<<| |>> -> + Swift::Storage::Server[$container_port] -> + Swift::Storage::Server[$account_port] -> + Swift::Storage::Server[$object_port] + +} diff --git a/site.pp b/site.pp new file mode 100644 index 00000000..e69de29b diff --git a/templates/check_galera_cluster b/templates/check_galera_cluster new file mode 100644 index 00000000..fde41719 --- /dev/null +++ b/templates/check_galera_cluster @@ -0,0 +1,15 @@ +#!/bin/bash + +MYSQL_USERNAME="clustercheckuser" +MYSQL_PASSWORD="clustercheckpassword!" +ERR_FILE="/dev/null" +AVAILABLE_WHEN_DONOR=0 +WSREP_STATUS=`mysql --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} -e "SHOW STATUS LIKE 'wsrep_local_state';" 2>${ERR_FILE} | awk '{if (NR!=1){print $2}}' 2>${ERR_FILE}` + +if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]; then + echo "OK - Percona XtraDB Cluster Node is synced." + exit 0 +else + echo "CRITICAL - Percona XtraDB Cluster Node is not synced." + exit 2 +fi diff --git a/templates/check_swift_recon b/templates/check_swift_recon new file mode 100755 index 00000000..a0ea3f4e --- /dev/null +++ b/templates/check_swift_recon @@ -0,0 +1,123 @@ +#!/bin/bash +# +# check_swift_recon - Check OpenStack Swift recon values +# +# Copyright © 2012 eNovance +# +# Author: Mehdi Abaakouk +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + + +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +PROGNAME=`basename $0` +REVISION="1.0" + +STATE_OK=0 +STATE_WARNING=1 +STATE_CRITICAL=2 +STATE_UNKNOWN=3 +STATE_DEPENDENT=4 + + +print_usage() { + echo "Usage: $PROGNAME [--field|-f] FIELD [[--critical|-c] VALUE [--warning|-w] VALUE]" +} + +print_help() { + print_usage + echo "This plugin checks Swift status using the swift-recon program." + exit 1 +} + +while [ "$1" ]; do + case "$1" in + --help|-h) + print_help + exit 0 + ;; + --field|-f) + field=$2 + shift ; shift + ;; + --critical|-c) + critical=$2 + shift ; shift + ;; + --warning|-w) + warning=$2 + shift ; shift + ;; + esac +done + +[ ! "$field" ] && print_help + +if ! which swift-recon >/dev/null 2>&1 +then + echo "swift-recon command not found" + exit $STATE_UNKNOWN +fi + + +case $field in + async_pending) + opt="--async" + ;; + replication_time) + opt="--replication" + ;; + ALL_auditor|ZBF_auditor) + opt="--auditor" + ;; + updater_last_sweep) + opt="--updater" + ;; + object_expiration_pass|expired_last_pass) + opt="--expirer" + ;; + quarantined_objects|quarantined_accounts|quarantined_containers) + opt="--quarantined" + ;; + orphan|tcp_in_use|time_wait|tcp6_in_use|tcp_mem_allocated_bytes) + opt="--sockstat" + ;; +esac + +data=$(swift-recon $opt | sed -n 's/^\['$field'\] //gp') +eval $(echo $data | sed -n 's/^low: \([[:digit:]\.]*\), high: \([[:digit:]\.]*\), avg: \([[:digit:]\.]*\), total: \([[:digit:]\.]*\), Failed: \([[:digit:]\.]*\)%, no_result: \([[:digit:]\.]*\), reported: \([[:digit:]\.]*\)/low="\1";high="\2";avg="\3";total="\4";failed="\5";no_result="\6";reported="\7"/gp') + +# no +failed=$(( ${failed/./} / 10 )) # change percent in perthousand +avg=$(( ${avg/./} / 10 )) # change percent in perthousand + +if [ "$no_result" != "0" ]; then + echo "CRITICAL - $data" + exit $STATE_CRITICAL +elif [ "$failed" != "0" ]; then + echo "CRITICAL - $data" + exit $STATE_CRITICAL +elif [ -n "$critical" -a -n "$warning" ]; then + if [ $avg -ge $warning -a $avg -lt $critical ]; then + echo "WARNING - $data" + exit $STATE_WARNING + elif [ $avg -ge $critical ]; then + echo "CRITICAL - $data" + exit $STATE_CRITICAL + fi +fi +echo "OK - $data" +exit $STATE_OK diff --git a/templates/clustercheck b/templates/clustercheck new file mode 100755 index 00000000..a72fd7b5 --- /dev/null +++ b/templates/clustercheck @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Script to make a proxy (ie HAProxy) capable of monitoring Percona XtraDB Cluster nodes properly +# +# Author: Olaf van Zandwijk +# Documentation and download: https://github.com/olafz/percona-clustercheck +# +# Based on the original script from Unai Rodriguez +# + +MYSQL_USERNAME="clustercheckuser" +MYSQL_PASSWORD="clustercheckpassword!" +ERR_FILE="/dev/null" +AVAILABLE_WHEN_DONOR=0 + +# +# Perform the query to check the wsrep_local_state +# +WSREP_STATUS=`mysql --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} -e "SHOW STATUS LIKE 'wsrep_local_state';" 2>${ERR_FILE} | awk '{if (NR!=1){print $2}}' 2>${ERR_FILE}` + +if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]] +then + # Percona XtraDB Cluster node local state is 'Synced' => return HTTP 200 + /bin/echo -en "HTTP/1.1 200 OK\r\n" + /bin/echo -en "Content-Type: text/plain\r\n" + /bin/echo -en "\r\n" + /bin/echo -en "Mariadb Cluster Node is synced.\r\n" + /bin/echo -en "\r\n" +else + # Percona XtraDB Cluster node local state is not 'Synced' => return HTTP 503 + /bin/echo -en "HTTP/1.1 503 Service Unavailable\r\n" + /bin/echo -en "Content-Type: text/plain\r\n" + /bin/echo -en "\r\n" + /bin/echo -en "Mariadb Cluster Node is not synced.\r\n" + /bin/echo -en "\r\n" +fi diff --git a/templates/munin/munin-node.conf.Ubuntu b/templates/munin/munin-node.conf.Ubuntu new file mode 100644 index 00000000..49a49c79 --- /dev/null +++ b/templates/munin/munin-node.conf.Ubuntu @@ -0,0 +1,54 @@ +# +# Example config-file for munin-node +# + +log_level 4 +log_file /var/log/munin/munin-node.log +pid_file /var/run/munin/munin-node.pid + +background 1 +setsid 1 + +user root +group root + + +# Regexps for files to ignore +ignore_file [\#~]$ +ignore_file DEADJOE$ +ignore_file \.bak$ +ignore_file %$ +ignore_file \.dpkg-(tmp|new|old|dist)$ +ignore_file \.rpm(save|new)$ +ignore_file \.pod$ + +# Set this if the client doesn't report the correct hostname when +# telnetting to localhost, port 4949 +# +#host_name localhost.localdomain + +# A list of addresses that are allowed to connect. This must be a +# regular expression, since Net::Server does not understand CIDR-style +# network notation unless the perl module Net::CIDR is installed. You +# may repeat the allow line as many times as you'd like + +allow ^127\.0\.0\.1$ +allow ^::1$ + +# If you have installed the Net::CIDR perl module, you can use one or more +# cidr_allow and cidr_deny address/mask patterns. A connecting client must +# match any cidr_allow, and not match any cidr_deny. Note that a netmask +# *must* be provided, even if it's /32 +# +# Example: +# +# cidr_allow 127.0.0.1/32 +# cidr_allow 192.0.2.0/24 +# cidr_deny 192.0.2.42/32 + +# Which address to bind to; +host * +# host 127.0.0.1 + +# And which port +port 4949 diff --git a/templates/munin/munin-node.conf.Ubuntu.precise b/templates/munin/munin-node.conf.Ubuntu.precise new file mode 100644 index 00000000..49a49c79 --- /dev/null +++ b/templates/munin/munin-node.conf.Ubuntu.precise @@ -0,0 +1,54 @@ +# +# Example config-file for munin-node +# + +log_level 4 +log_file /var/log/munin/munin-node.log +pid_file /var/run/munin/munin-node.pid + +background 1 +setsid 1 + +user root +group root + + +# Regexps for files to ignore +ignore_file [\#~]$ +ignore_file DEADJOE$ +ignore_file \.bak$ +ignore_file %$ +ignore_file \.dpkg-(tmp|new|old|dist)$ +ignore_file \.rpm(save|new)$ +ignore_file \.pod$ + +# Set this if the client doesn't report the correct hostname when +# telnetting to localhost, port 4949 +# +#host_name localhost.localdomain + +# A list of addresses that are allowed to connect. This must be a +# regular expression, since Net::Server does not understand CIDR-style +# network notation unless the perl module Net::CIDR is installed. You +# may repeat the allow line as many times as you'd like + +allow ^127\.0\.0\.1$ +allow ^::1$ + +# If you have installed the Net::CIDR perl module, you can use one or more +# cidr_allow and cidr_deny address/mask patterns. A connecting client must +# match any cidr_allow, and not match any cidr_deny. Note that a netmask +# *must* be provided, even if it's /32 +# +# Example: +# +# cidr_allow 127.0.0.1/32 +# cidr_allow 192.0.2.0/24 +# cidr_deny 192.0.2.42/32 + +# Which address to bind to; +host * +# host 127.0.0.1 + +# And which port +port 4949 diff --git a/templates/mysqlchk b/templates/mysqlchk new file mode 100644 index 00000000..8de373d8 --- /dev/null +++ b/templates/mysqlchk @@ -0,0 +1,18 @@ +# default: on +# description: mysqlchk +service mysqlchk +{ +# this is a config for xinetd, place it in /etc/xinetd.d/ + disable = no + flags = REUSE + socket_type = stream + port = 9200 + wait = no + user = nobody + server = /usr/bin/clustercheck + log_on_failure += USERID + only_from = 0.0.0.0/0 + # recommended to put the IPs that need + # to connect exclusively (security purposes) + per_source = UNLIMITED +}