Nova keypair support
Now Trove doesn't support to specify keypair when creating the db instance, the ssh key is injected into the guest agent image at the build time, which makes it very hard to manage. This patch adds a config option `nova_keypair` that is used as keypair name when creating db instance. The old way of the image building will be changed in the subsequent patches. Change-Id: I41d4e41fc4bc413cdd48b8d761429b0204481932 Story: #2005429 Task: #30462
This commit is contained in:
parent
f4e17a34b9
commit
a3de34dbc7
@ -0,0 +1,13 @@
|
||||
features:
|
||||
- Added a new config option ``nova_keypair`` to specify an existing Nova
|
||||
keypair name for the database instance creation, the cloud administrator is
|
||||
responsible for the keypair management and configuration. It's recommended
|
||||
to create Trove database instance in the admin project for security
|
||||
reasons, so only the cloud administrator who has the private key can access
|
||||
the database instance. With the keypair support, ssh keys are no longer
|
||||
injected into Trove guest agent image at build time.
|
||||
upgrade:
|
||||
- Cloud administrator needs to create a Nova keypair and specify the keypair
|
||||
name for config option ``nova_keypair``, the private key is used to ssh
|
||||
into new database instances created. The previous private key is also
|
||||
needed to ssh into the existing database instances.
|
@ -81,6 +81,10 @@ common_opts = [
|
||||
help="The version of the image service client."),
|
||||
cfg.BoolOpt('nova_api_insecure', default=False,
|
||||
help="Allow to perform insecure SSL requests to nova."),
|
||||
cfg.StrOpt('nova_keypair', default=None,
|
||||
help="Name of a Nova keypair to inject into a database "
|
||||
"instance to enable SSH access. The keypair should be "
|
||||
"prior created by the cloud operator."),
|
||||
cfg.URIOpt('neutron_url', help='URL without the tenant segment.'),
|
||||
cfg.StrOpt('neutron_service_type', default='network',
|
||||
help='Service type to use when searching catalog.'),
|
||||
|
@ -890,14 +890,16 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
name = self.hostname or self.name
|
||||
bdmap_v2 = block_device_mapping_v2
|
||||
config_drive = CONF.use_nova_server_config_drive
|
||||
key_name = CONF.nova_keypair
|
||||
|
||||
server = self.nova_client.servers.create(
|
||||
name, image_id, flavor_id, files=files, userdata=userdata,
|
||||
security_groups=security_groups, block_device_mapping_v2=bdmap_v2,
|
||||
availability_zone=availability_zone, nics=nics,
|
||||
config_drive=config_drive, scheduler_hints=scheduler_hints)
|
||||
config_drive=config_drive, scheduler_hints=scheduler_hints,
|
||||
key_name=key_name)
|
||||
LOG.debug("Created new compute instance %(server_id)s "
|
||||
"for instance %(id)s",
|
||||
"for database instance %(id)s",
|
||||
{'server_id': server.id, 'id': self.id})
|
||||
return server
|
||||
|
||||
|
@ -101,7 +101,7 @@ class FakeServer(object):
|
||||
next_local_id = 0
|
||||
|
||||
def __init__(self, parent, owner, id, name, image_id, flavor_ref,
|
||||
volumes):
|
||||
volumes, key_name):
|
||||
self.owner = owner # This is a context.
|
||||
self.id = id
|
||||
self.parent = parent
|
||||
@ -125,6 +125,7 @@ class FakeServer(object):
|
||||
setattr(self, 'OS-EXT-AZ:availability_zone', 'nova')
|
||||
|
||||
self._info = {'os:volumes': info_vols}
|
||||
self.key_name = key_name
|
||||
|
||||
@property
|
||||
def addresses(self):
|
||||
@ -268,11 +269,11 @@ class FakeServers(object):
|
||||
def create(self, name, image_id, flavor_ref, files=None, userdata=None,
|
||||
block_device_mapping_v2=None, security_groups=None,
|
||||
availability_zone=None, nics=None, config_drive=False,
|
||||
scheduler_hints=None):
|
||||
scheduler_hints=None, key_name=None):
|
||||
id = "FAKE_%s" % uuid.uuid4()
|
||||
volumes = self._get_volumes_from_bdm_v2(block_device_mapping_v2)
|
||||
server = FakeServer(self, self.context, id, name, image_id, flavor_ref,
|
||||
volumes)
|
||||
volumes, key_name)
|
||||
self.db[id] = server
|
||||
if name.endswith('SERVER_ERROR'):
|
||||
raise nova_exceptions.ClientException("Fake server create error.")
|
||||
|
@ -79,6 +79,7 @@ class fake_Server(object):
|
||||
self.security_groups = None
|
||||
self.block_device_mapping_v2 = None
|
||||
self.status = 'ACTIVE'
|
||||
self.key_name = None
|
||||
|
||||
|
||||
class fake_ServerManager(object):
|
||||
@ -86,7 +87,7 @@ class fake_ServerManager(object):
|
||||
security_groups, block_device_mapping_v2=None,
|
||||
availability_zone=None,
|
||||
nics=None, config_drive=False,
|
||||
scheduler_hints=None):
|
||||
scheduler_hints=None, key_name=None):
|
||||
server = fake_Server()
|
||||
server.id = "server_id"
|
||||
server.name = name
|
||||
@ -98,6 +99,8 @@ class fake_ServerManager(object):
|
||||
server.block_device_mapping_v2 = block_device_mapping_v2
|
||||
server.availability_zone = availability_zone
|
||||
server.nics = nics
|
||||
server.key_name = key_name
|
||||
|
||||
return server
|
||||
|
||||
|
||||
@ -239,6 +242,14 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
|
||||
None, None, None, datastore_manager, None, None, None)
|
||||
self.assertEqual(server.userdata, self.userdata)
|
||||
|
||||
def test_create_instance_with_keypair(self):
|
||||
cfg.CONF.set_override('nova_keypair', 'fake_keypair')
|
||||
|
||||
server = self.freshinstancetasks._create_server(
|
||||
None, None, None, None, None, None, None)
|
||||
|
||||
self.assertEqual('fake_keypair', server.key_name)
|
||||
|
||||
@patch.object(DBInstance, 'get_by')
|
||||
def test_create_instance_guestconfig(self, patch_get_by):
|
||||
cfg.CONF.set_override('guest_config', self.guestconfig)
|
||||
@ -303,15 +314,18 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
|
||||
self.freshinstancetasks._create_server('fake-flavor', 'fake-image',
|
||||
None, 'mysql', None, None,
|
||||
None)
|
||||
mock_servers_create.assert_called_with('fake-hostname', 'fake-image',
|
||||
'fake-flavor', files={},
|
||||
userdata=None,
|
||||
security_groups=None,
|
||||
block_device_mapping_v2=None,
|
||||
availability_zone=None,
|
||||
nics=None,
|
||||
config_drive=True,
|
||||
scheduler_hints=None)
|
||||
mock_servers_create.assert_called_with(
|
||||
'fake-hostname', 'fake-image',
|
||||
'fake-flavor', files={},
|
||||
userdata=None,
|
||||
security_groups=None,
|
||||
block_device_mapping_v2=None,
|
||||
availability_zone=None,
|
||||
nics=None,
|
||||
config_drive=True,
|
||||
scheduler_hints=None,
|
||||
key_name=None
|
||||
)
|
||||
|
||||
@patch.object(InstanceServiceStatus, 'find_by',
|
||||
return_value=fake_InstanceServiceStatus.find_by())
|
||||
|
Loading…
Reference in New Issue
Block a user