Merge "Add --trusted-image-cert option for server create"
This commit is contained in:
@@ -1171,6 +1171,19 @@ class CreateServer(command.ShowOne):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help=_('Wait for build to complete'),
|
help=_('Wait for build to complete'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--trusted-image-cert',
|
||||||
|
metavar='<trusted-cert-id>',
|
||||||
|
action='append',
|
||||||
|
dest='trusted_image_certs',
|
||||||
|
help=_(
|
||||||
|
'Trusted image certificate IDs used to validate certificates '
|
||||||
|
'during the image signature verification process. '
|
||||||
|
'May be specified multiple times to pass multiple trusted '
|
||||||
|
'image certificate IDs. '
|
||||||
|
'(supported by --os-compute-api-version 2.63 or above)'
|
||||||
|
),
|
||||||
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@@ -1640,6 +1653,24 @@ class CreateServer(command.ShowOne):
|
|||||||
|
|
||||||
boot_kwargs['hostname'] = parsed_args.hostname
|
boot_kwargs['hostname'] = parsed_args.hostname
|
||||||
|
|
||||||
|
# TODO(stephenfin): Handle OS_TRUSTED_IMAGE_CERTIFICATE_IDS
|
||||||
|
if parsed_args.trusted_image_certs:
|
||||||
|
if not (image and not parsed_args.boot_from_volume):
|
||||||
|
msg = _(
|
||||||
|
'--trusted-image-cert option is only supported for '
|
||||||
|
'servers booted directly from images'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
if compute_client.api_version < api_versions.APIVersion('2.63'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.63 or greater is required to '
|
||||||
|
'support the --trusted-image-cert option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
certs = parsed_args.trusted_image_certs
|
||||||
|
boot_kwargs['trusted_image_certificates'] = certs
|
||||||
|
|
||||||
LOG.debug('boot_args: %s', boot_args)
|
LOG.debug('boot_args: %s', boot_args)
|
||||||
LOG.debug('boot_kwargs: %s', boot_kwargs)
|
LOG.debug('boot_kwargs: %s', boot_kwargs)
|
||||||
|
|
||||||
@@ -3277,7 +3308,6 @@ class RebuildServer(command.ShowOne):
|
|||||||
help=_(
|
help=_(
|
||||||
'Trusted image certificate IDs used to validate certificates '
|
'Trusted image certificate IDs used to validate certificates '
|
||||||
'during the image signature verification process. '
|
'during the image signature verification process. '
|
||||||
'Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. '
|
|
||||||
'May be specified multiple times to pass multiple trusted '
|
'May be specified multiple times to pass multiple trusted '
|
||||||
'image certificate IDs. '
|
'image certificate IDs. '
|
||||||
'Cannot be specified with the --no-trusted-certs option. '
|
'Cannot be specified with the --no-trusted-certs option. '
|
||||||
|
@@ -3624,6 +3624,156 @@ class TestServerCreate(TestServer):
|
|||||||
exceptions.CommandError, self.cmd.take_action,
|
exceptions.CommandError, self.cmd.take_action,
|
||||||
parsed_args)
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_create_with_trusted_image_cert(self):
|
||||||
|
self.app.client_manager.compute.api_version = \
|
||||||
|
api_versions.APIVersion('2.63')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--trusted-image-cert', 'foo',
|
||||||
|
'--trusted-image-cert', 'bar',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('config_drive', False),
|
||||||
|
('trusted_image_certs', ['foo', 'bar']),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
# Set expected values
|
||||||
|
kwargs = dict(
|
||||||
|
meta=None,
|
||||||
|
files={},
|
||||||
|
reservation_id=None,
|
||||||
|
min_count=1,
|
||||||
|
max_count=1,
|
||||||
|
security_groups=[],
|
||||||
|
userdata=None,
|
||||||
|
key_name=None,
|
||||||
|
availability_zone=None,
|
||||||
|
admin_pass=None,
|
||||||
|
block_device_mapping_v2=[],
|
||||||
|
nics='auto',
|
||||||
|
scheduler_hints={},
|
||||||
|
config_drive=None,
|
||||||
|
trusted_image_certificates=['foo', 'bar'],
|
||||||
|
)
|
||||||
|
# ServerManager.create(name, image, flavor, **kwargs)
|
||||||
|
self.servers_mock.create.assert_called_with(
|
||||||
|
self.new_server.name,
|
||||||
|
self.image,
|
||||||
|
self.flavor,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.datalist(), data)
|
||||||
|
self.assertFalse(self.images_mock.called)
|
||||||
|
self.assertFalse(self.flavors_mock.called)
|
||||||
|
|
||||||
|
def test_server_create_with_trusted_image_cert_prev263(self):
|
||||||
|
self.app.client_manager.compute.api_version = \
|
||||||
|
api_versions.APIVersion('2.62')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--trusted-image-cert', 'foo',
|
||||||
|
'--trusted-image-cert', 'bar',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('config_drive', False),
|
||||||
|
('trusted_image_certs', ['foo', 'bar']),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_create_with_trusted_image_cert_from_volume(self):
|
||||||
|
self.app.client_manager.compute.api_version = \
|
||||||
|
api_versions.APIVersion('2.63')
|
||||||
|
arglist = [
|
||||||
|
'--volume', 'volume1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--trusted-image-cert', 'foo',
|
||||||
|
'--trusted-image-cert', 'bar',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('volume', 'volume1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('config_drive', False),
|
||||||
|
('trusted_image_certs', ['foo', 'bar']),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_create_with_trusted_image_cert_from_snapshot(self):
|
||||||
|
self.app.client_manager.compute.api_version = \
|
||||||
|
api_versions.APIVersion('2.63')
|
||||||
|
arglist = [
|
||||||
|
'--snapshot', 'snapshot1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--trusted-image-cert', 'foo',
|
||||||
|
'--trusted-image-cert', 'bar',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('snapshot', 'snapshot1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('config_drive', False),
|
||||||
|
('trusted_image_certs', ['foo', 'bar']),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_create_with_trusted_image_cert_boot_from_volume(self):
|
||||||
|
self.app.client_manager.compute.api_version = \
|
||||||
|
api_versions.APIVersion('2.63')
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--boot-from-volume', '1',
|
||||||
|
'--trusted-image-cert', 'foo',
|
||||||
|
'--trusted-image-cert', 'bar',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('boot_from_volume', 1),
|
||||||
|
('config_drive', False),
|
||||||
|
('trusted_image_certs', ['foo', 'bar']),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class TestServerDelete(TestServer):
|
class TestServerDelete(TestServer):
|
||||||
|
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added ``--trusted-image-cert`` option for server create. It is available
|
||||||
|
only when directly booting server from image (not from volume, not from
|
||||||
|
snapshot and not via image converted to volume first).
|
||||||
|
This option is supported for Compute API version >=2.63
|
Reference in New Issue
Block a user