Configure migration SSH tunnel
authorOliver Walsh <owalsh@redhat.com>
Tue, 28 Mar 2017 15:02:18 +0000 (16:02 +0100)
committerOliver Walsh <owalsh@redhat.com>
Mon, 3 Apr 2017 08:12:55 +0000 (09:12 +0100)
This patch configures SSH tunneling for nova cold-migration and reuses the
tunnel for libvirt live-migration unless TLS has been enabled.

Change-Id: I367757cbe8757d11943af7e41af620f9ce919a06
Depends-On: Iac1763761c652bed637cb7cf85bc12347b5fe7ec

manifests/profile/base/nova.pp
releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml [new file with mode: 0644]
spec/classes/tripleo_profile_base_nova_spec.rb

index 36425f6..ab9b615 100644 (file)
 #   (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,
@@ -99,6 +108,8 @@ class tripleo::profile::base::nova (
   $oslomsg_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
@@ -114,7 +125,62 @@ class tripleo::profile::base::nova (
 
   if $step >= 4 or ($step >= 3 and $sync_db) {
     $oslomsg_use_ssl_real = sprintf('%s', bool2num(str2bool($oslomsg_use_ssl)))
-    class { '::nova' :
+    include ::nova::config
+    class { '::nova::cache':
+      enabled          => true,
+      backend          => 'oslo_cache.memcache_pool',
+      memcache_servers => $memcache_servers,
+    }
+    include ::nova::placement
+
+    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' => $oslomsg_rpc_proto,
         'hosts'     => $oslomsg_rpc_hosts,
@@ -131,23 +197,8 @@ class tripleo::profile::base::nova (
         'password'  => $oslomsg_notify_password,
         'ssl'       => $oslomsg_use_ssl_real,
       }),
+      nova_public_key            => $nova_public_key,
+      nova_private_key           => $nova_private_key,
     }
-    include ::nova::config
-    class { '::nova::cache':
-      enabled          => true,
-      backend          => 'oslo_cache.memcache_pool',
-      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,
-      }
-    }
-  }
-
 }
diff --git a/releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml b/releasenotes/notes/cold_migration_setup-dc4ebd834920c27f.yaml
new file mode 100644 (file)
index 0000000..00b7799
--- /dev/null
@@ -0,0 +1,4 @@
+---
+features:
+  - Configure ssh tunneling for nova cold-migration. Re-use the tunnel for
+    libvirt live-migration unless TLS is enabled.
index b5677cc..8f7bfdc 100644 (file)
@@ -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',
+        :oslomsg_rpc_hosts => [ 'localhost' ],
+        :oslomsg_rpc_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',
+        :oslomsg_rpc_hosts => [ 'localhost' ],
+        :oslomsg_rpc_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',
+        :oslomsg_rpc_hosts => [ 'localhost' ],
+        :oslomsg_rpc_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]
         )