diff options
-rw-r--r-- | manifests/profile/base/gnocchi/api.pp | 4 | ||||
-rw-r--r-- | manifests/profile/base/nova.pp | 87 | ||||
-rw-r--r-- | releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml | 4 | ||||
-rw-r--r-- | spec/classes/tripleo_profile_base_gnocchi_api_spec.rb | 101 | ||||
-rw-r--r-- | spec/classes/tripleo_profile_base_nova_spec.rb | 118 | ||||
-rw-r--r-- | spec/fixtures/hieradata/default.yaml | 2 |
6 files changed, 294 insertions, 22 deletions
diff --git a/manifests/profile/base/gnocchi/api.pp b/manifests/profile/base/gnocchi/api.pp index 92431e4..029eb99 100644 --- a/manifests/profile/base/gnocchi/api.pp +++ b/manifests/profile/base/gnocchi/api.pp @@ -96,14 +96,16 @@ class tripleo::profile::base::gnocchi::api ( include ::gnocchi::db::sync } - if $step >= 4 { + if $step >= 3 { include ::gnocchi::api include ::apache::mod::ssl class { '::gnocchi::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, } + } + if $step >= 4 { class { '::gnocchi::storage': coordination_url => join(['redis://:', hiera('gnocchi_redis_password'), '@', normalize_ip_for_uri(hiera('redis_vip')), ':6379/']), } diff --git a/manifests/profile/base/nova.pp b/manifests/profile/base/nova.pp index cb34521..b4330a9 100644 --- a/manifests/profile/base/nova.pp +++ b/manifests/profile/base/nova.pp @@ -62,6 +62,15 @@ # (Optional) The current step of the deployment # Defaults to hiera('step') # +# [*migration_ssh_key*] +# (Optional) SSH key pair for migration SSH tunnel. +# Expects a hash with keys 'private_key' and 'public_key'. +# Defaults to {} +# +# [*libvirt_tls*] +# (Optional) Whether or not libvird TLS service is enabled. +# Defaults to false + class tripleo::profile::base::nova ( $bootstrap_node = hiera('bootstrap_nodeid', undef), $libvirt_enabled = false, @@ -74,6 +83,8 @@ class tripleo::profile::base::nova ( $messaging_use_ssl = hiera('nova::rabbit_use_ssl', '0'), $nova_compute_enabled = false, $step = hiera('step'), + $migration_ssh_key = {}, + $libvirt_tls = false ) { if $::hostname == downcase($bootstrap_node) { $sync_db = true @@ -89,18 +100,6 @@ class tripleo::profile::base::nova ( if $step >= 4 or ($step >= 3 and $sync_db) { $messaging_use_ssl_real = sprintf('%s', bool2num(str2bool($messaging_use_ssl))) - # TODO(ccamacho): remove sprintf once we properly type the port, needs - # to be a string for the os_transport_url function. - class { '::nova' : - default_transport_url => os_transport_url({ - 'transport' => $messaging_driver, - 'hosts' => $messaging_hosts, - 'port' => sprintf('%s', $messaging_port), - 'username' => $messaging_username, - 'password' => $messaging_password, - 'ssl' => $messaging_use_ssl_real, - }), - } include ::nova::config class { '::nova::cache': enabled => true, @@ -108,15 +107,65 @@ class tripleo::profile::base::nova ( memcache_servers => $memcache_servers, } include ::nova::placement - } - if $step >= 4 { - if $manage_migration { - class { '::nova::migration::libvirt': - configure_libvirt => $libvirt_enabled, - configure_nova => $nova_compute_enabled, + if $step >= 4 and $manage_migration { + + # Libvirt setup (live-migration) + if $libvirt_tls { + class { '::nova::migration::libvirt': + transport => 'tls', + configure_libvirt => $libvirt_enabled, + configure_nova => $nova_compute_enabled, + } + } else { + # Reuse the cold-migration SSH tunnel when TLS is not enabled + class { '::nova::migration::libvirt': + transport => 'ssh', + configure_libvirt => $libvirt_enabled, + configure_nova => $nova_compute_enabled, + client_user => 'nova', + client_extraparams => {'keyfile' => '/var/lib/nova/.ssh/id_rsa'} + } } + + if $migration_ssh_key != {} { + # Nova SSH tunnel setup (cold-migration) + + #TODO: Remove me when https://review.rdoproject.org/r/#/c/4008 lands + user { 'nova': + ensure => present, + shell => '/bin/bash', + } + + $private_key_parts = split($migration_ssh_key['public_key'], ' ') + $nova_public_key = { + 'type' => $private_key_parts[0], + key => $private_key_parts[1] + } + $nova_private_key = { + 'type' => $private_key_parts[0], + key => $migration_ssh_key['private_key'] + } + } else { + $nova_public_key = undef + $nova_private_key = undef + } + } else { + $nova_public_key = undef + $nova_private_key = undef } - } + class { '::nova' : + default_transport_url => os_transport_url({ + 'transport' => $messaging_driver, + 'hosts' => $messaging_hosts, + 'port' => sprintf('%s', $messaging_port), + 'username' => $messaging_username, + 'password' => $messaging_password, + 'ssl' => $messaging_use_ssl_real, + }), + nova_public_key => $nova_public_key, + nova_private_key => $nova_private_key, + } + } } diff --git a/releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml b/releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml new file mode 100644 index 0000000..00b7799 --- /dev/null +++ b/releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml @@ -0,0 +1,4 @@ +--- +features: + - Configure ssh tunneling for nova cold-migration. Re-use the tunnel for + libvirt live-migration unless TLS is enabled. diff --git a/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb b/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb new file mode 100644 index 0000000..805a28e --- /dev/null +++ b/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb @@ -0,0 +1,101 @@ +# +# Copyright (C) 2017 Red Hat, Inc. +# +# 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. +# + +require 'spec_helper' + +describe 'tripleo::profile::base::gnocchi::api' do + shared_examples_for 'tripleo::profile::base::gnocchi::api' do + let(:pre_condition) do + "class { '::tripleo::profile::base::gnocchi': step => #{params[:step]}, }" + end + + context 'with step less than 3' do + let(:params) { { :step => 2 } } + + it { + is_expected.to contain_class('tripleo::profile::base::gnocchi::api') + is_expected.to_not contain_class('gnocchi::api') + is_expected.to_not contain_class('gnocchi::wsgi::apache') + } + end + + context 'with step 3 on bootstrap' do + let(:params) { { + :step => 3, + :bootstrap_node => 'node.example.com', + } } + + it { + is_expected.to contain_class('gnocchi::db::sync') + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + } + end + + context 'with step 3' do + let(:params) { { + :step => 3, + } } + + it { + is_expected.to_not contain_class('gnocchi::db::sync') + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + } + end + + # TODO(aschultz): fix profile class to not include hiera look ups in the + # step 4 so we can properly test it + #context 'with step 4' do + # let(:params) { { + # :step => 4, + # } } + # + # it { + # is_expected.to contain_class('gnocchi::api') + # is_expected.to contain_class('gnocchi::wsgi::apache') + # is_expected.to contain_class('gnocchi::storage') + # } + #end + # + #context 'with step 5 on bootstrap' do + # let(:params) { { + # :step => 5, + # :bootstrap_node => 'node.example.com' + # } } + # + # it { + # is_expected.to contain_class('gnocchi::api') + # is_expected.to contain_class('gnocchi::wsgi::apache') + # is_expected.to contain_exec('run gnocchi upgrade with storage').with( + # :command => 'gnocchi-upgrade --config-file=/etc/gnocchi/gnocchi.conf', + # :path => ['/usr/bin', '/usr/sbin'] + # ) + # } + #end + end + + + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts.merge({ :hostname => 'node.example.com' }) + end + + it_behaves_like 'tripleo::profile::base::gnocchi::api' + end + end +end diff --git a/spec/classes/tripleo_profile_base_nova_spec.rb b/spec/classes/tripleo_profile_base_nova_spec.rb index 68b01e9..9056034 100644 --- a/spec/classes/tripleo_profile_base_nova_spec.rb +++ b/spec/classes/tripleo_profile_base_nova_spec.rb @@ -85,7 +85,12 @@ describe 'tripleo::profile::base::nova' do it { is_expected.to contain_class('tripleo::profile::base::nova') - is_expected.to contain_class('nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => nil, + :nova_private_key => nil, + ) is_expected.to contain_class('nova::config') is_expected.to contain_class('nova::cache') is_expected.to contain_class('nova::placement') @@ -109,11 +114,120 @@ describe 'tripleo::profile::base::nova' do it { is_expected.to contain_class('tripleo::profile::base::nova') - is_expected.to contain_class('nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => nil, + :nova_private_key => nil, + ) + is_expected.to contain_class('nova::config') + is_expected.to contain_class('nova::placement') + is_expected.to contain_class('nova::cache') + is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'ssh', + :configure_libvirt => params[:libvirt_enabled], + :configure_nova => params[:nova_compute_enabled] + ) + } + end + + context 'with step 4 with libvirt TLS' do + let(:pre_condition) { + 'include ::nova::compute::libvirt::services' + } + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :messaging_hosts => [ 'localhost' ], + :messaging_password => 'foo', + :libvirt_tls => true, + } } + + it { + is_expected.to contain_class('tripleo::profile::base::nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => nil, + :nova_private_key => nil, + ) + is_expected.to contain_class('nova::config') + is_expected.to contain_class('nova::placement') + is_expected.to contain_class('nova::cache') + is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'tls', + :configure_libvirt => params[:libvirt_enabled], + :configure_nova => params[:nova_compute_enabled], + ) + } + end + + context 'with step 4 with libvirt and migration ssh key' do + let(:pre_condition) { + 'include ::nova::compute::libvirt::services' + } + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :messaging_hosts => [ 'localhost' ], + :messaging_password => 'foo', + :migration_ssh_key => { 'private_key' => 'foo', 'public_key' => 'ssh-rsa bar'} + } } + + it { + is_expected.to contain_class('tripleo::profile::base::nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => {'key' => 'bar', 'type' => 'ssh-rsa'}, + :nova_private_key => {'key' => 'foo', 'type' => 'ssh-rsa'} + ) + is_expected.to contain_class('nova::config') + is_expected.to contain_class('nova::placement') + is_expected.to contain_class('nova::cache') + is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'ssh', + :configure_libvirt => params[:libvirt_enabled], + :configure_nova => params[:nova_compute_enabled] + ) + } + end + + context 'with step 4 with libvirt TLS and migration ssh key' do + let(:pre_condition) { + 'include ::nova::compute::libvirt::services' + } + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :messaging_hosts => [ 'localhost' ], + :messaging_password => 'foo', + :libvirt_tls => true, + :migration_ssh_key => { 'private_key' => 'foo', 'public_key' => 'ssh-rsa bar'} + } } + + it { + is_expected.to contain_class('tripleo::profile::base::nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => {'key' => 'bar', 'type' => 'ssh-rsa'}, + :nova_private_key => {'key' => 'foo', 'type' => 'ssh-rsa'} + ) is_expected.to contain_class('nova::config') is_expected.to contain_class('nova::placement') is_expected.to contain_class('nova::cache') is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'tls', :configure_libvirt => params[:libvirt_enabled], :configure_nova => params[:nova_compute_enabled] ) diff --git a/spec/fixtures/hieradata/default.yaml b/spec/fixtures/hieradata/default.yaml index 592c308..94d2b28 100644 --- a/spec/fixtures/hieradata/default.yaml +++ b/spec/fixtures/hieradata/default.yaml @@ -24,6 +24,8 @@ ceph::profile::params::rgw_keystone_admin_password: 'keystone_admin_password' # cinder related items cinder::rabbit_password: 'password' cinder::keystone::authtoken::password: 'password' +# gnocchi related items +gnocchi::keystone::authtoken::password: 'password' # nova related items nova::rabbit_password: 'password' nova::keystone::authtoken::password: 'password' |