Merge "Microversion 2.63 - Add trusted_image_certificates"
This commit is contained in:
commit
910328c30d
|
@ -1011,6 +1011,7 @@ nova boot
|
|||
[--config-drive <value>] [--poll] [--admin-pass <value>]
|
||||
[--access-ip-v4 <value>] [--access-ip-v6 <value>]
|
||||
[--description <description>]
|
||||
[--trusted-image-certificate-id]
|
||||
<name>
|
||||
|
||||
Boot a new server.
|
||||
|
@ -1164,6 +1165,13 @@ Boot a new server.
|
|||
Description for the server. (Supported by API
|
||||
versions '2.19' - '2.latest')
|
||||
|
||||
``--trusted-image-certificate-id <trusted-image-certificate-id>``
|
||||
Trusted image certificate IDs used to validate certificates
|
||||
during the image signature verification process.
|
||||
Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS].
|
||||
May be specified multiple times to pass multiple trusted image
|
||||
certificate IDs. (Supported by API versions '2.63' - '2.latest')
|
||||
|
||||
.. _nova_cell-capacities:
|
||||
|
||||
nova cell-capacities
|
||||
|
@ -2683,6 +2691,8 @@ nova rebuild
|
|||
[--minimal] [--preserve-ephemeral] [--name <name>]
|
||||
[--description <description>] [--meta <key=value>]
|
||||
[--file <dst-path=src-path>]
|
||||
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
||||
[--trusted-image-certificates-unset]
|
||||
<server> <image>
|
||||
|
||||
Shutdown, re-image, and re-boot a server.
|
||||
|
@ -2730,6 +2740,18 @@ Shutdown, re-image, and re-boot a server.
|
|||
to <dst-path> on the new server. You may store
|
||||
up to 5 files.
|
||||
|
||||
``--trusted-image-certificate-id <trusted-image-certificate-id>``
|
||||
Trusted image certificate IDs used to validate certificates
|
||||
during the image signature verification process.
|
||||
Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS].
|
||||
May be specified multiple times to pass multiple trusted image
|
||||
certificate IDs. (Supported by API versions '2.63' - '2.latest')
|
||||
|
||||
``--trusted-image-certificates-unset``
|
||||
Unset trusted_image_certificates in the server. Cannot be
|
||||
specified with the ``--trusted-image-certificate-id`` option.
|
||||
(Supported by API versions '2.63' - '2.latest')
|
||||
|
||||
.. _nova_refresh-network:
|
||||
|
||||
nova refresh-network
|
||||
|
|
|
@ -60,6 +60,16 @@ some environment variables:
|
|||
The Keystone region name. Defaults to the first region if multiple regions
|
||||
are available.
|
||||
|
||||
.. envvar:: OS_TRUSTED_IMAGE_CERTIFICATE_IDS
|
||||
|
||||
A comma-delimited list of trusted image certificate IDs. Only used
|
||||
with the ``nova boot`` and ``nova rebuild`` commands starting with the
|
||||
2.63 microversion.
|
||||
|
||||
For example::
|
||||
|
||||
export OS_TRUSTED_IMAGE_CERTIFICATE_IDS=trusted-cert-id1,trusted-cert-id2
|
||||
|
||||
For example, in Bash you'd use::
|
||||
|
||||
export OS_USERNAME=yourname
|
||||
|
|
|
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
|||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.62")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.63")
|
||||
|
|
|
@ -1542,3 +1542,70 @@ class ServersV257Test(ServersV256Test):
|
|||
exceptions.UnsupportedAttribute, s.rebuild, image=1, name='new',
|
||||
meta={'foo': 'bar'}, files=files)
|
||||
self.assertIn('files', six.text_type(ex))
|
||||
|
||||
|
||||
class ServersV263Test(ServersV257Test):
|
||||
|
||||
api_version = "2.63"
|
||||
|
||||
def test_create_server_with_trusted_image_certificates(self):
|
||||
self.cs.servers.create(
|
||||
name="My server",
|
||||
image=1,
|
||||
flavor=1,
|
||||
meta={'foo': 'bar'},
|
||||
userdata="hello moto",
|
||||
key_name="fakekey",
|
||||
nics=self._get_server_create_default_nics(),
|
||||
trusted_image_certificates=['id1', 'id2'],
|
||||
)
|
||||
self.assert_called('POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'imageRef': '1',
|
||||
'key_name': 'fakekey',
|
||||
'max_count': 1,
|
||||
'metadata': {'foo': 'bar'},
|
||||
'min_count': 1,
|
||||
'name': 'My server',
|
||||
'networks': 'auto',
|
||||
'trusted_image_certificates': ['id1', 'id2'],
|
||||
'user_data': 'aGVsbG8gbW90bw=='
|
||||
}}
|
||||
)
|
||||
|
||||
def test_create_server_with_trusted_image_certificates_pre_263_fails(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.62')
|
||||
ex = self.assertRaises(
|
||||
exceptions.UnsupportedAttribute, self.cs.servers.create,
|
||||
name="My server", image=1, flavor=1, meta={'foo': 'bar'},
|
||||
userdata="hello moto", key_name="fakekey",
|
||||
nics=self._get_server_create_default_nics(),
|
||||
trusted_image_certificates=['id1', 'id2'])
|
||||
self.assertIn('trusted_image_certificates', six.text_type(ex))
|
||||
|
||||
def test_rebuild_server_with_trusted_image_certificates(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.rebuild(image="1", trusted_image_certificates=['id1', 'id2'])
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {
|
||||
'imageRef': '1',
|
||||
'trusted_image_certificates': ['id1', 'id2']}})
|
||||
|
||||
def test_rebuild_server_with_trusted_image_certificates_none(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.rebuild(image="1", trusted_image_certificates=None)
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {
|
||||
'imageRef': '1',
|
||||
'trusted_image_certificates': None}})
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_pre_263_fails(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.62')
|
||||
ex = self.assertRaises(exceptions.UnsupportedAttribute,
|
||||
self.cs.servers.rebuild,
|
||||
'1234', fakes.FAKE_IMAGE_UUID_1,
|
||||
trusted_image_certificates=['id1', 'id2'])
|
||||
self.assertIn('trusted_image_certificates', six.text_type(ex))
|
||||
|
|
|
@ -1155,6 +1155,113 @@ class ShellTest(utils.TestCase):
|
|||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.51')
|
||||
|
||||
def test_boot_with_single_trusted_image_certificates(self):
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto some-server '
|
||||
'--trusted-image-certificate-id id1'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'trusted_image_certificates': ['id1']
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_multiple_trusted_image_certificates(self):
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto some-server '
|
||||
'--trusted-image-certificate-id id1 '
|
||||
'--trusted-image-certificate-id id2'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'trusted_image_certificates': ['id1', 'id2']
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_trusted_image_certificates_envar(self):
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2'))
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto some-server'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'trusted_image_certificates': ['var_id1', 'var_id2']
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_without_trusted_image_certificates_v263(self):
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto some-server'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_trusted_image_certificates_pre_v263(self):
|
||||
cmd = ('boot --flavor 1 --image %s some-server '
|
||||
'--trusted-image-certificate-id id1 '
|
||||
'--trusted-image-certificate-id id2' % FAKE_UUID_1)
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.62')
|
||||
|
||||
# OS_TRUSTED_IMAGE_CERTIFICATE_IDS environment variable is not supported in
|
||||
# microversions < 2.63 (should result in an UnsupportedAttribute exception)
|
||||
def test_boot_with_trusted_image_certificates_envar_pre_v263(self):
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2'))
|
||||
cmd = ('boot --flavor 1 --image %s --nic auto some-server '
|
||||
% FAKE_UUID_1)
|
||||
self.assertRaises(exceptions.UnsupportedAttribute, self.run_command,
|
||||
cmd, api_version='2.62')
|
||||
|
||||
def test_boot_with_trusted_image_certificates_arg_and_envvar(self):
|
||||
"""Tests that if both the environment variable and argument are
|
||||
specified, the argument takes precedence.
|
||||
"""
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'cert1'))
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto '
|
||||
'--trusted-image-certificate-id cert2 some-server'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'trusted_image_certificates': ['cert2']
|
||||
}},
|
||||
)
|
||||
|
||||
def test_flavor_list(self):
|
||||
out, _ = self.run_command('flavor-list')
|
||||
self.assert_called_anytime('GET', '/flavors/detail')
|
||||
|
@ -1664,6 +1771,148 @@ class ShellTest(utils.TestCase):
|
|||
self.assertIn("Cannot specify '--user-data-unset' with "
|
||||
"'--user-data'.", six.text_type(ex))
|
||||
|
||||
def test_rebuild_with_single_trusted_image_certificates(self):
|
||||
self.run_command('rebuild sample-server %s '
|
||||
'--trusted-image-certificate-id id1'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
'trusted_image_certificates': ['id1']
|
||||
}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_rebuild_with_multiple_trusted_image_certificate_ids(self):
|
||||
self.run_command('rebuild sample-server %s '
|
||||
'--trusted-image-certificate-id id1 '
|
||||
'--trusted-image-certificate-id id2'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
'trusted_image_certificates': ['id1',
|
||||
'id2']
|
||||
}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_envar(self):
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2'))
|
||||
self.run_command('rebuild sample-server %s'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
'trusted_image_certificates':
|
||||
['var_id1', 'var_id2']}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_rebuild_without_trusted_image_certificates_v263(self):
|
||||
self.run_command('rebuild sample-server %s' % FAKE_UUID_1,
|
||||
api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_pre_v263(self):
|
||||
cmd = ('rebuild sample-server %s'
|
||||
'--trusted-image-certificate-id id1 '
|
||||
'--trusted-image-certificate-id id2' % FAKE_UUID_1)
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.62')
|
||||
|
||||
# OS_TRUSTED_IMAGE_CERTIFICATE_IDS environment variable is not supported in
|
||||
# microversions < 2.63 (should result in an UnsupportedAttribute exception)
|
||||
def test_rebuild_with_trusted_image_certificates_envar_pre_v263(self):
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2'))
|
||||
cmd = ('rebuild sample-server %s' % FAKE_UUID_1)
|
||||
self.assertRaises(exceptions.UnsupportedAttribute, self.run_command,
|
||||
cmd, api_version='2.62')
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_unset(self):
|
||||
"""Tests explicitly unsetting the existing server trusted image
|
||||
certificate IDs.
|
||||
"""
|
||||
self.run_command('rebuild sample-server %s '
|
||||
'--trusted-image-certificates-unset'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
'trusted_image_certificates': None
|
||||
}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_unset_arg_conflict(self):
|
||||
"""Tests the error condition that trusted image certs are both unset
|
||||
and set via argument during rebuild.
|
||||
"""
|
||||
ex = self.assertRaises(
|
||||
exceptions.CommandError, self.run_command,
|
||||
'rebuild sample-server %s --trusted-image-certificate-id id1 '
|
||||
'--trusted-image-certificates-unset' % FAKE_UUID_1,
|
||||
api_version='2.63')
|
||||
self.assertIn("Cannot specify '--trusted-image-certificates-unset' "
|
||||
"with '--trusted-image-certificate-id'",
|
||||
six.text_type(ex))
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_unset_env_conflict(self):
|
||||
"""Tests the error condition that trusted image certs are both unset
|
||||
and set via environment variable during rebuild.
|
||||
"""
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1'))
|
||||
ex = self.assertRaises(
|
||||
exceptions.CommandError, self.run_command,
|
||||
'rebuild sample-server %s --trusted-image-certificates-unset' %
|
||||
FAKE_UUID_1, api_version='2.63')
|
||||
self.assertIn("Cannot specify '--trusted-image-certificates-unset' "
|
||||
"with '--trusted-image-certificate-id'",
|
||||
six.text_type(ex))
|
||||
|
||||
def test_rebuild_with_trusted_image_certificates_arg_and_envar(self):
|
||||
"""Tests that if both the environment variable and argument are
|
||||
specified, the argument takes precedence.
|
||||
"""
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'cert1'))
|
||||
self.run_command('rebuild sample-server '
|
||||
'--trusted-image-certificate-id cert2 %s'
|
||||
% FAKE_UUID_1, api_version='2.63')
|
||||
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||
self.assert_called('GET', '/servers/1234', pos=1)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'rebuild': {'imageRef': FAKE_UUID_1,
|
||||
'description': None,
|
||||
'trusted_image_certificates':
|
||||
['cert2']}
|
||||
}, pos=3)
|
||||
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||
|
||||
def test_start(self):
|
||||
self.run_command('start sample-server')
|
||||
self.assert_called('POST', '/servers/1234/action', {'os-start': None})
|
||||
|
@ -3547,6 +3796,7 @@ class ShellTest(utils.TestCase):
|
|||
60, # There are no client-side changes for volume multiattach.
|
||||
61, # There are no version-wrapped shell method changes for this.
|
||||
62, # There are no version-wrapped shell method changes for this.
|
||||
63, # There are no version-wrapped shell method changes for this.
|
||||
])
|
||||
versions_supported = set(range(0,
|
||||
novaclient.API_MAX_VERSION.ver_minor + 1))
|
||||
|
|
|
@ -650,7 +650,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
block_device_mapping_v2=None, nics=None, scheduler_hints=None,
|
||||
config_drive=None, admin_pass=None, disk_config=None,
|
||||
access_ip_v4=None, access_ip_v6=None, description=None,
|
||||
tags=None, **kwargs):
|
||||
tags=None, trusted_image_certificates=None, **kwargs):
|
||||
"""
|
||||
Create (boot) a new server.
|
||||
"""
|
||||
|
@ -768,6 +768,10 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
if tags:
|
||||
body['server']['tags'] = tags
|
||||
|
||||
if trusted_image_certificates:
|
||||
body['server']['trusted_image_certificates'] = (
|
||||
trusted_image_certificates)
|
||||
|
||||
return self._create('/servers', body, response_key,
|
||||
return_raw=return_raw, **kwargs)
|
||||
|
||||
|
@ -1191,7 +1195,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
block_device_mapping=None, block_device_mapping_v2=None,
|
||||
nics=None, scheduler_hints=None,
|
||||
config_drive=None, disk_config=None, admin_pass=None,
|
||||
access_ip_v4=None, access_ip_v6=None, **kwargs):
|
||||
access_ip_v4=None, access_ip_v6=None,
|
||||
trusted_image_certificates=None, **kwargs):
|
||||
# TODO(anthony): indicate in doc string if param is an extension
|
||||
# and/or optional
|
||||
"""
|
||||
|
@ -1252,6 +1257,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
microversion 2.19)
|
||||
:param tags: A list of arbitrary strings to be added to the
|
||||
server as tags (allowed since microversion 2.52)
|
||||
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||
(allowed since microversion 2.63)
|
||||
"""
|
||||
if not min_count:
|
||||
min_count = 1
|
||||
|
@ -1292,6 +1299,12 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
if files and self.api_version >= personality_files_deprecation:
|
||||
raise exceptions.UnsupportedAttribute('files', '2.0', '2.56')
|
||||
|
||||
trusted_certs_microversion = api_versions.APIVersion("2.63")
|
||||
if (trusted_image_certificates and
|
||||
self.api_version < trusted_certs_microversion):
|
||||
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
||||
"2.63")
|
||||
|
||||
boot_kwargs = dict(
|
||||
meta=meta, files=files, userdata=userdata,
|
||||
reservation_id=reservation_id, min_count=min_count,
|
||||
|
@ -1299,7 +1312,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
key_name=key_name, availability_zone=availability_zone,
|
||||
scheduler_hints=scheduler_hints, config_drive=config_drive,
|
||||
disk_config=disk_config, admin_pass=admin_pass,
|
||||
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, **kwargs)
|
||||
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
||||
trusted_image_certificates=trusted_image_certificates, **kwargs)
|
||||
|
||||
if block_device_mapping:
|
||||
boot_kwargs['block_device_mapping'] = block_device_mapping
|
||||
|
@ -1416,6 +1430,9 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
well or a string. If None is specified, the existing
|
||||
user_data is unset.
|
||||
(starting from microversion 2.57)
|
||||
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||
or None to unset/reset the servers trusted image
|
||||
certificates (allowed since microversion 2.63)
|
||||
:returns: :class:`Server`
|
||||
"""
|
||||
descr_microversion = api_versions.APIVersion("2.19")
|
||||
|
@ -1436,6 +1453,15 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
if 'userdata' in kwargs and self.api_version < files_and_userdata:
|
||||
raise exceptions.UnsupportedAttribute('userdata', '2.57')
|
||||
|
||||
trusted_certs_microversion = api_versions.APIVersion("2.63")
|
||||
# trusted_image_certificates is intentionally *not* a named kwarg
|
||||
# so that trusted_image_certificates=None is not confused with an
|
||||
# intentional unset/reset request.
|
||||
if ("trusted_image_certificates" in kwargs and
|
||||
self.api_version < trusted_certs_microversion):
|
||||
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
||||
"2.63")
|
||||
|
||||
body = {'imageRef': base.getid(image)}
|
||||
if password is not None:
|
||||
body['adminPass'] = password
|
||||
|
@ -1449,6 +1475,9 @@ class ServerManager(base.BootingManagerWithFind):
|
|||
body["description"] = kwargs["description"]
|
||||
if 'key_name' in kwargs:
|
||||
body['key_name'] = kwargs['key_name']
|
||||
if "trusted_image_certificates" in kwargs:
|
||||
body["trusted_image_certificates"] = kwargs[
|
||||
"trusted_image_certificates"]
|
||||
if meta:
|
||||
body['metadata'] = meta
|
||||
if files:
|
||||
|
|
|
@ -510,6 +510,14 @@ def _boot(cs, args):
|
|||
if include_files:
|
||||
boot_kwargs['files'] = files
|
||||
|
||||
if ('trusted_image_certificates' in args and
|
||||
args.trusted_image_certificates):
|
||||
boot_kwargs['trusted_image_certificates'] = (
|
||||
args.trusted_image_certificates)
|
||||
elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
|
||||
boot_kwargs["trusted_image_certificates"] = utils.env(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS').split(',')
|
||||
|
||||
return boot_args, boot_kwargs
|
||||
|
||||
|
||||
|
@ -874,6 +882,18 @@ def _boot(cs, args):
|
|||
action="store_true",
|
||||
default=False,
|
||||
help=_("Return a reservation id bound to created servers."))
|
||||
@utils.arg(
|
||||
'--trusted-image-certificate-id',
|
||||
metavar='<trusted-image-certificate-id>',
|
||||
action='append',
|
||||
dest='trusted_image_certificates',
|
||||
default=[],
|
||||
help=_('Trusted image certificate IDs used to validate certificates '
|
||||
'during the image signature verification process. '
|
||||
'Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. '
|
||||
'May be specified multiple times to pass multiple trusted image '
|
||||
'certificate IDs.'),
|
||||
start_version="2.63")
|
||||
def do_boot(cs, args):
|
||||
"""Boot a new server."""
|
||||
boot_args, boot_kwargs = _boot(cs, args)
|
||||
|
@ -1807,6 +1827,25 @@ def do_reboot(cs, args):
|
|||
help=_("Unset user_data in the server. Cannot be specified with the "
|
||||
"'--user-data' option."),
|
||||
start_version='2.57')
|
||||
@utils.arg(
|
||||
'--trusted-image-certificate-id',
|
||||
metavar='<trusted-image-certificate-id>',
|
||||
action='append',
|
||||
dest='trusted_image_certificates',
|
||||
default=[],
|
||||
help=_('Trusted image certificate IDs used to validate certificates '
|
||||
'during the image signature verification process. '
|
||||
'Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. '
|
||||
'May be specified multiple times to pass multiple trusted image '
|
||||
'certificate IDs.'),
|
||||
start_version="2.63")
|
||||
@utils.arg(
|
||||
'--trusted-image-certificates-unset',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Unset trusted_image_certificates in the server. Cannot be "
|
||||
"specified with the '--trusted-image-certificate-id' option."),
|
||||
start_version="2.63")
|
||||
def do_rebuild(cs, args):
|
||||
"""Shutdown, re-image, and re-boot a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
|
@ -1861,6 +1900,33 @@ def do_rebuild(cs, args):
|
|||
elif args.key_name:
|
||||
kwargs['key_name'] = args.key_name
|
||||
|
||||
if cs.api_version >= api_versions.APIVersion('2.63'):
|
||||
# First determine if the user specified anything via the command line
|
||||
# or the environment variable.
|
||||
trusted_image_certificates = None
|
||||
if ('trusted_image_certificates' in args and
|
||||
args.trusted_image_certificates):
|
||||
trusted_image_certificates = args.trusted_image_certificates
|
||||
elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
|
||||
trusted_image_certificates = utils.env(
|
||||
'OS_TRUSTED_IMAGE_CERTIFICATE_IDS').split(',')
|
||||
|
||||
if args.trusted_image_certificates_unset:
|
||||
kwargs['trusted_image_certificates'] = None
|
||||
# Check for conflicts in option usage.
|
||||
if trusted_image_certificates:
|
||||
raise exceptions.CommandError(
|
||||
_("Cannot specify '--trusted-image-certificates-unset' "
|
||||
"with '--trusted-image-certificate-id' or with "
|
||||
"OS_TRUSTED_IMAGE_CERTIFICATE_IDS env variable set."))
|
||||
elif trusted_image_certificates:
|
||||
# Only specify the kwarg if there is a value specified to avoid
|
||||
# confusion with unsetting the value.
|
||||
kwargs['trusted_image_certificates'] = trusted_image_certificates
|
||||
elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
|
||||
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
||||
"2.63")
|
||||
|
||||
server = server.rebuild(image, _password, **kwargs)
|
||||
_print_server(cs, args, server)
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Added support for `microversion 2.63`_, which includes the following
|
||||
changes:
|
||||
|
||||
- New environment variable called ``OS_TRUSTED_IMAGE_CERTIFICATE_IDS``
|
||||
- New ``nova boot`` option called ``--trusted-image-certificate-id``
|
||||
- New ``nova rebuild`` options called ``--trusted-image-certificate-id``
|
||||
and ``--trusted-image-certificates-unset``
|
||||
- New kwarg called ``trusted_image_certificates`` added to python API
|
||||
bindings:
|
||||
|
||||
- ``novaclient.v2.servers.ServerManager.create()``
|
||||
- ``novaclient.v2.servers.ServerManager.rebuild()``
|
||||
|
||||
.. _microversion 2.63: https://docs.openstack.org/nova/latest/api_microversion_history.html#id57
|
Loading…
Reference in New Issue