support for managing ssh keys

This change permits provisioning ssh public and private keys as part of
creating the "nova" user.  There are no changes to the default behavior
of the module.  This changes introduces three new parameters:

- nova_public_key
- nova_private_key
- nova_shell

These changes are intended to permit configuring live migration via
qemu+ssh connections to remote hypervisors.

Change-Id: Ib61f4574843a7e5ada9a08692f4488cb844c9eee
Implements: blueprint provision-ssh-keys
This commit is contained in:
Lars Kellogg-Stedman
2014-04-09 11:20:16 -04:00
parent e4156d7237
commit 4f73f440a6
2 changed files with 194 additions and 3 deletions

View File

@@ -189,6 +189,22 @@
# the ownership of all files/dirs owned by nova.
# Defaults to undef.
#
# [*nova_public_key*]
# (optional) Install public key in .ssh/authorized_keys for the 'nova' user.
# Expects a hash of the form { type => 'key-type', key => 'key-data' } where
# 'key-type' is one of (ssh-rsa, ssh-dsa, ssh-ecdsa) and 'key-data' is the
# actual key data (e.g, 'AAAA...').
#
# [*nova_private_key*]
# (optional) Install private key into .ssh/id_rsa (or appropriate equivalent
# for key type). Expects a hash of the form { type => 'key-type', key =>
# 'key-data' }, where 'key-type' is one of (ssh-rsa, ssh-dsa, ssh-ecdsa) and
# 'key-data' is the contents of the private key file.
#
# [*nova_shell*]
# (optional) Set shell for 'nova' user to the specified value.
# Defaults to '/bin/false'.
#
# [*mysql_module*]
# (optional) Mysql module version to use. Tested versions
# are 0.9 and 2.2
@@ -257,6 +273,9 @@ class nova(
$rootwrap_config = '/etc/nova/rootwrap.conf',
$nova_user_id = undef,
$nova_group_id = undef,
$nova_public_key = undef,
$nova_private_key = undef,
$nova_shell = '/bin/false',
# deprecated in folsom
#$root_helper = $::nova::params::root_helper,
$monitoring_notifications = false,
@@ -293,11 +312,60 @@ class nova(
groups => 'nova',
home => '/var/lib/nova',
managehome => false,
shell => '/bin/false',
shell => $nova_shell,
uid => $nova_user_id,
gid => $nova_group_id,
}
if $nova_public_key or $nova_private_key {
file { '/var/lib/nova/.ssh':
ensure => directory,
mode => '0700',
owner => nova,
group => nova,
}
if $nova_public_key {
if ! $nova_public_key[key] or ! $nova_public_key[type] {
fail('You must provide both a key type and key data.')
}
ssh_authorized_key { 'nova-migration-public-key':
ensure => present,
key => $nova_public_key[key],
type => $nova_public_key[type],
user => 'nova',
require => File['/var/lib/nova/.ssh'],
}
}
if $nova_private_key {
if ! $nova_private_key[key] or ! $nova_private_key[type] {
fail('You must provide both a key type and key data.')
}
$nova_private_key_file = $nova_private_key[type] ? {
'ssh-rsa' => '/var/lib/nova/.ssh/id_rsa',
'ssh-dsa' => '/var/lib/nova/.ssh/id_dsa',
'ssh-ecdsa' => '/var/lib/nova/.ssh/id_ecdsa',
default => undef
}
if ! $nova_private_key_file {
fail("Unable to determine name of private key file. Type specified was '${nova_private_key[type]}' but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.")
}
file { $nova_private_key_file:
content => $nova_private_key[key],
mode => '0600',
owner => nova,
group => nova,
require => File['/var/lib/nova/.ssh'],
}
}
}
# all nova_config resources should be applied
# after the nova common package
# before the file resource for nova.conf is managed

View File

@@ -132,7 +132,8 @@ describe 'nova' do
:notify_api_faults => true,
:nova_user_id => '499',
:nova_group_id => '499',
:report_interval => '60' }
:report_interval => '60',
:nova_shell => '/bin/bash' }
end
it 'creates user and group' do
@@ -148,7 +149,7 @@ describe 'nova' do
:groups => 'nova',
:home => '/var/lib/nova',
:managehome => false,
:shell => '/bin/false',
:shell => '/bin/bash',
:uid => '499',
:gid => '499'
)
@@ -412,6 +413,128 @@ describe 'nova' do
it { should contain_nova_config('DEFAULT/qpid_sasl_mechanisms').with_value('DIGEST-MD5 GSSAPI PLAIN') }
end
end
context 'with ssh public key' do
let :params do
{
:nova_public_key => {'type' => 'ssh-rsa',
'key' => 'keydata'}
}
end
it 'should install ssh public key' do
should contain_ssh_authorized_key('nova-migration-public-key').with(
:ensure => 'present',
:key => 'keydata',
:type => 'ssh-rsa'
)
end
end
context 'with ssh public key missing key type' do
let :params do
{
:nova_public_key => {'type' => '',
'key' => 'keydata'}
}
end
it 'should raise an error' do
expect {
should contain_ssh_authorized_key('nova-migration-public-key').with(
:ensure => 'present',
:key => 'keydata',
:type => ''
)
}.to raise_error Puppet::Error, /You must provide both a key type and key data./
end
end
context 'with ssh public key missing key data' do
let :params do
{
:nova_public_key => {'type' => 'ssh-rsa',
'key' => ''}
}
end
it 'should raise an error' do
expect {
should contain_ssh_authorized_key('nova-migration-public-key').with(
:ensure => 'present',
:key => 'keydata',
:type => ''
)
}.to raise_error Puppet::Error, /You must provide both a key type and key data./
end
end
context 'with ssh private key' do
let :params do
{
:nova_private_key => {'type' => 'ssh-rsa',
'key' => 'keydata'}
}
end
it 'should install ssh private key' do
should contain_file('/var/lib/nova/.ssh/id_rsa').with(
:content => 'keydata'
)
end
end
context 'with ssh private key missing key type' do
let :params do
{
:nova_private_key => {'type' => '',
'key' => 'keydata'}
}
end
it 'should raise an error' do
expect {
should contain_file('/var/lib/nova/.ssh/id_rsa').with(
:content => 'keydata'
)
}.to raise_error Puppet::Error, /You must provide both a key type and key data./
end
end
context 'with ssh private key having incorrect key type' do
let :params do
{
:nova_private_key => {'type' => 'invalid',
'key' => 'keydata'}
}
end
it 'should raise an error' do
expect {
should contain_file('/var/lib/nova/.ssh/id_rsa').with(
:content => 'keydata'
)
}.to raise_error Puppet::Error, /Unable to determine name of private key file./
end
end
context 'with ssh private key missing key data' do
let :params do
{
:nova_private_key => {'type' => 'ssh-rsa',
'key' => ''}
}
end
it 'should raise an error' do
expect {
should contain_file('/var/lib/nova/.ssh/id_rsa').with(
:content => 'keydata'
)
}.to raise_error Puppet::Error, /You must provide both a key type and key data./
end
end
end
context 'on Debian platforms' do