From 9cf11371ac3a99648e21518059bfa310655769e0 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 19 Dec 2014 21:48:45 -0500 Subject: Puppet: overcloud controller config This patch provides an alternate implementation of the OS::TripleO::Controller::SoftwareConfig which uses Puppet to drive the configuration. Using this it is possible to create a fully functional overcloud controller instance which has the controller node configured via Puppet stackforge modules. Initially this includes only the following services: MySQL RabbitMQ Keepalived/HAProxy (HA is not yet fully supported however) Nova Neutron Keystone Glance (file backend) Cinder Using these services it is possible to run devtest_overcloud.sh to completion. The idea is that we can quickly add more services once we have CI in place. In order to test this you'll want to build your images with these elements: os-net-config heat-config-puppet puppet-modules hiera None of the OpenStack specific TripleO elements should be used with this approach (the nova/neutron elements were NOT used to build the controller image). Also, rather than use neutron-openvswitch-agent to configure low level networking it is recommended that os-net-config by configured directly via heat modeling rather than parameter passing to init-neutron-ovs. This allows us to configure the physical network while avoiding the coupling to the neutron-openvswitch-element that our standard parameter driven networking currently uses. (We still need to move init-neutron-ovs so that it isn't coupled and/or deprecate its use entirely because the heat drive stuff is more flexible.) Packages may optionally be pre-installed via DIB using the -p option (-p openstack-neutron,openstack-nova) etc. Change-Id: If8462e4eacb08eced61a8b03fd7c3c4257e0b5b8 --- puppet/hieradata/controller.yaml | 43 +++++ puppet/loadbalancer.pp | 375 +++++++++++++++++++++++++++++++++++++++ puppet/overcloud_controller.pp | 209 ++++++++++++++++++++++ 3 files changed, 627 insertions(+) create mode 100644 puppet/hieradata/controller.yaml create mode 100644 puppet/loadbalancer.pp create mode 100644 puppet/overcloud_controller.pp (limited to 'puppet') diff --git a/puppet/hieradata/controller.yaml b/puppet/hieradata/controller.yaml new file mode 100644 index 00000000..874d383b --- /dev/null +++ b/puppet/hieradata/controller.yaml @@ -0,0 +1,43 @@ +# Hiera data here applies to all controller nodes +nova::api::enabled: true +nova::conductor::enabled: true +nova::consoleauth::enabled: true +nova::vncproxy::enabled: true +nova::scheduler::enabled: true + +rabbitmq::delete_guest_user: false +rabbitmq::wipe_db_on_cookie_change: true +rabbitmq::port: '5672' +rabbitmq::package_source: undef +rabbitmq::repos_ensure: false + +# service tenant +nova::api::admin_tenant_name: 'service' +glance::api::keystone_tenant: 'service' +glance::registry::keystone_tenant: 'service' +neutron::server::auth_tenant: 'service' +neutron::agents::metadata::auth_tenant: 'service' +cinder::api::keystone_tenant: 'service' + +# glance +glance::api::pipeline: 'keystone' +glance::registry::pipeline: 'keystone' +glance::registry::manage_service: true + +# neutron +neutron::core_plugin: 'ml2' +neutron::service_plugins: + - 'neutron.services.l3_router.l3_router_plugin.L3RouterPlugin' +neutron::dhcp_agents_per_network: 2 +neutron::plugins::ml2::tunnel_id_ranges: + - '1:1000' +neutron::server::sync_db: true + +# nova +nova::notify_on_state_change: 'vm_and_task_state' +nova::api::osapi_v3: true + +# cinder +cinder::scheduler::scheduler_driver: cinder.scheduler.filter_scheduler.FilterScheduler + +mysql::server::manage_config_file: true diff --git a/puppet/loadbalancer.pp b/puppet/loadbalancer.pp new file mode 100644 index 00000000..ea834c5e --- /dev/null +++ b/puppet/loadbalancer.pp @@ -0,0 +1,375 @@ +# Copyright 2014 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class tripleo::loadbalancer ( + $keystone_admin = false, + $keystone_public = false, + $neutron = false, + $cinder = false, + $glance_api = false, + $glance_registry = false, + $nova_ec2 = false, + $nova_osapi = false, + $nova_metadata = false, + $nova_novncproxy = false, + $ceilometer = false, + $swift_proxy_server = false, + $heat_api = false, + $heat_cloudwatch = false, + $heat_cfn = false, + $horizon = false, + $mysql = false, + $rabbitmq = false, +) { + + case $::osfamily { + 'RedHat': { + $keepalived_name_is_process = false + $keepalived_vrrp_script = 'systemctl status haproxy.service' + } # RedHat + 'Debian': { + $keepalived_name_is_process = true + $keepalived_vrrp_script = undef + } + } + + class { 'keepalived': } + keepalived::vrrp_script { 'haproxy': + name_is_process => $keepalived_name_is_process, + script => $keepalived_vrrp_script, + } + + # KEEPALIVE INSTANCE CONTROL + keepalived::instance { '51': + interface => hiera('control_virtual_interface'), + virtual_ips => [join([hiera('controller_virtual_ip'), ' dev ', hiera('control_virtual_interface')])], + state => 'MASTER', + track_script => ['haproxy'], + priority => 101, + } + + # KEEPALIVE INSTANCE PUBLIC + keepalived::instance { '52': + interface => hiera('public_virtual_interface'), + virtual_ips => [join([hiera('public_virtual_ip'), ' dev ', hiera('public_virtual_interface')])], + state => 'MASTER', + track_script => ['haproxy'], + priority => 101, + } + + sysctl::value { 'net.ipv4.ip_nonlocal_bind': value => '1' } + + class { 'haproxy': + global_options => { + 'log' => '/dev/log local0', + 'pidfile' => '/var/run/haproxy.pid', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'maxconn' => '4000', + }, + defaults_options => { + 'mode' => 'tcp', + 'log' => 'global', + 'retries' => '3', + 'maxconn' => '150', + 'option' => [ 'tcpka', 'tcplog' ], + 'timeout' => [ 'http-request 10s', 'queue 1m', 'connect 10s', 'client 1m', 'server 1m', 'check 10s' ], + }, + } + + haproxy::listen { 'haproxy.stats': + ipaddress => '*', + ports => '1993', + mode => 'http', + options => { + 'stats' => 'enable', + }, + collect_exported => false, + } + + if $keystone_admin { + haproxy::listen { 'keystone_admin': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 35357, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'keystone_admin': + listening_service => 'keystone_admin', + ports => '35357', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $keystone_public { + haproxy::listen { 'keystone_public': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 5000, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'keystone_public': + listening_service => 'keystone_public', + ports => '5000', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $neutron { + haproxy::listen { 'neutron': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 9696, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'neutron': + listening_service => 'neutron', + ports => '9696', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $cinder { + haproxy::listen { 'cinder': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8776, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'cinder': + listening_service => 'cinder', + ports => '8776', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $glance_api { + haproxy::listen { 'glance_api': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 9292, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'glance_api': + listening_service => 'glance_api', + ports => '9292', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + + if $glance_registry { + haproxy::listen { 'glance_registry': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 9191, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'glance_registry': + listening_service => 'glance_registry', + ports => '9191', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $nova_ec2 { + haproxy::listen { 'nova_ec2': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8773, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'nova_ec2': + listening_service => 'nova_ec2', + ports => '8773', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $nova_osapi { + haproxy::listen { 'nova_osapi': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8774, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'nova_osapi': + listening_service => 'nova_osapi', + ports => '8774', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $nova_metadata { + haproxy::listen { 'nova_metadata': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8775, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'nova_metadata': + listening_service => 'nova_metadata', + ports => '8775', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $nova_novncproxy { + haproxy::listen { 'nova_novncproxy': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 6080, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'nova_novncproxy': + listening_service => 'nova_novncproxy', + ports => '6080', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $ceilometer { + haproxy::listen { 'ceilometer': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8777, + collect_exported => false, + } + haproxy::balancermember { 'ceilometer': + listening_service => 'ceilometer', + ports => '8777', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $swift_proxy_server { + haproxy::listen { 'swift_proxy_server': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8080, + options => { 'option' => [ 'httpchk GET /info' ] }, + collect_exported => false, + } + haproxy::balancermember { 'swift_proxy_server': + listening_service => 'swift_proxy_server', + ports => '8080', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $heat_api { + haproxy::listen { 'heat_api': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8004, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'heat_api': + listening_service => 'heat_api', + ports => '8004', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $heat_cloudwatch { + haproxy::listen { 'heat_cloudwatch': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8003, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'heat_cloudwatch': + listening_service => 'heat_cloudwatch', + ports => '8003', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $heat_cfn { + haproxy::listen { 'heat_cfn': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 8000, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'heat_cfn': + listening_service => 'heat_cfn', + ports => '8000', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $horizon { + haproxy::listen { 'horizon': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 80, + options => { 'option' => [ 'httpchk GET /' ] }, + collect_exported => false, + } + haproxy::balancermember { 'horizon': + listening_service => 'horizon', + ports => '80', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $mysql { + haproxy::listen { 'mysql': + ipaddress => [hiera('controller_virtual_ip')], + ports => 3306, + options => { 'timeout' => [ 'client 0', 'server 0' ] }, + collect_exported => false, + } + haproxy::balancermember { 'mysql': + listening_service => 'mysql', + ports => '3306', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + + if $rabbitmq { + haproxy::listen { 'rabbitmq': + ipaddress => [hiera('controller_virtual_ip'), hiera('public_virtual_ip')], + ports => 5672, + options => { 'timeout' => [ 'client 0', 'server 0' ] }, + collect_exported => false, + } + haproxy::balancermember { 'rabbitmq': + listening_service => 'rabbitmq', + ports => '5672', + ipaddresses => hiera('controller_host'), + options => ['check', 'inter 2000', 'rise 2', 'fall 5'], + } + } + +} + +include ::tripleo::loadbalancer diff --git a/puppet/overcloud_controller.pp b/puppet/overcloud_controller.pp new file mode 100644 index 00000000..4c1306f2 --- /dev/null +++ b/puppet/overcloud_controller.pp @@ -0,0 +1,209 @@ +# Copyright 2014 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +if hiera('step') >= 1 { + + # TODO Galara + class { 'mysql::server': + override_options => { + 'mysqld' => { + 'bind-address' => hiera('controller_host') + } + } + } + + # FIXME: this should only occur on the bootstrap host (ditto for db syncs) + # Create all the database schemas + # Example DSN format: mysql://user:password@host/dbname + $allowed_hosts = ['%',hiera('controller_host')] + $keystone_dsn = split(hiera('keystone::database_connection'), '[@:/?]') + class { 'keystone::db::mysql': + user => $keystone_dsn[3], + password => $keystone_dsn[4], + host => $keystone_dsn[5], + dbname => $keystone_dsn[6], + allowed_hosts => $allowed_hosts, + } + $glance_dsn = split(hiera('glance::api::database_connection'), '[@:/?]') + class { 'glance::db::mysql': + user => $glance_dsn[3], + password => $glance_dsn[4], + host => $glance_dsn[5], + dbname => $glance_dsn[6], + allowed_hosts => $allowed_hosts, + } + $nova_dsn = split(hiera('nova::database_connection'), '[@:/?]') + class { 'nova::db::mysql': + user => $nova_dsn[3], + password => $nova_dsn[4], + host => $nova_dsn[5], + dbname => $nova_dsn[6], + allowed_hosts => $allowed_hosts, + } + $neutron_dsn = split(hiera('neutron::server::database_connection'), '[@:/?]') + class { 'neutron::db::mysql': + user => $neutron_dsn[3], + password => $neutron_dsn[4], + host => $neutron_dsn[5], + dbname => $neutron_dsn[6], + allowed_hosts => $allowed_hosts, + } + $cinder_dsn = split(hiera('cinder::database_connection'), '[@:/?]') + class { 'cinder::db::mysql': + user => $cinder_dsn[3], + password => $cinder_dsn[4], + host => $cinder_dsn[5], + dbname => $cinder_dsn[6], + allowed_hosts => $allowed_hosts, + } + $heat_dsn = split(hiera('heat_dsn'), '[@:/?]') + class { 'heat::db::mysql': + user => $heat_dsn[3], + password => $heat_dsn[4], + host => $heat_dsn[5], + dbname => $heat_dsn[6], + allowed_hosts => $allowed_hosts, + } + + if $::osfamily == 'RedHat' { + $rabbit_provider = 'yum' + } else { + $rabbit_provider = undef + } + + Class['rabbitmq'] -> Rabbitmq_vhost <| |> + Class['rabbitmq'] -> Rabbitmq_user <| |> + Class['rabbitmq'] -> Rabbitmq_user_permissions <| |> + + # TODO Rabbit HA + class { 'rabbitmq': + package_provider => $rabbit_provider, + config_cluster => false, + node_ip_address => hiera('controller_host'), + } + + rabbitmq_vhost { '/': + provider => 'rabbitmqctl', + } + rabbitmq_user { ['nova','glance','neutron','cinder','ceilometer','heat']: + admin => true, + password => hiera('rabbit_password'), + provider => 'rabbitmqctl', + } + + rabbitmq_user_permissions {[ + 'nova@/', + 'glance@/', + 'neutron@/', + 'cinder@/', + 'ceilometer@/', + 'heat@/', + ]: + configure_permission => '.*', + write_permission => '.*', + read_permission => '.*', + provider => 'rabbitmqctl', + } + +} #END STEP 1 + +if hiera('step') >= 2 { + + include ::keystone + + #TODO: need a cleanup-keystone-tokens.sh solution here + keystone_config { + 'ec2/driver': value => 'keystone.contrib.ec2.backends.sql.Ec2'; + } + file { [ '/etc/keystone/ssl', '/etc/keystone/ssl/certs', '/etc/keystone/ssl/private' ]: + ensure => 'directory', + owner => 'keystone', + group => 'keystone', + require => Package['keystone'], + } + file { '/etc/keystone/ssl/certs/signing_cert.pem': + content => hiera('keystone_signing_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + file { '/etc/keystone/ssl/private/signing_key.pem': + content => hiera('keystone_signing_key'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/private'], + } + file { '/etc/keystone/ssl/certs/ca.pem': + content => hiera('keystone_ca_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + + # TODO: swift backend, also notifications, scrubber, etc. + include ::glance::api + include ::glance::registry + + class { 'nova': + rabbit_hosts => [hiera('controller_virtual_ip')], + glance_api_servers => join([hiera('glance_protocol'), '://', hiera('controller_virtual_ip'), ':', hiera('glance_port')]), + } + + include ::nova::api + include ::nova::cert + include ::nova::conductor + include ::nova::consoleauth + include ::nova::vncproxy + include ::nova::scheduler + + class {'neutron': + rabbit_hosts => [hiera('controller_virtual_ip')], + } + + include ::neutron::server + include ::neutron::agents::dhcp + include ::neutron::agents::l3 + + class { 'neutron::plugins::ml2': + flat_networks => split(hiera('neutron_flat_networks'), ','), + tenant_network_types => [hiera('neutron_tenant_network_type')], + type_drivers => [hiera('neutron_tenant_network_type')], + } + + class { 'neutron::agents::ml2::ovs': + bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), + tunnel_types => split(hiera('neutron_tunnel_types'), ','), + } + + class { 'neutron::agents::metadata': + auth_url => join(['http://', hiera('controller_virtual_ip'), ':35357/v2.0']), + } + + class {'cinder': + rabbit_hosts => [hiera('controller_virtual_ip')], + } + + include ::cinder::api + include ::cinder::scheduler + include ::cinder::volume + include ::cinder::volume::iscsi + class {'cinder::setup_test_volume': + size => join([hiera('cinder_lvm_loop_device_size'), 'M']), + } + +} #END STEP 2 -- cgit 1.2.3-korg