
Closes-bug: #1737513 Depends-On: Ia3d80bf2f81c7317fec117aecbc3c560d51a7d4e Change-Id: I5032c71a3a0230df7352a415b5b77f37fafc29a7
133 lines
5.5 KiB
Python
133 lines
5.5 KiB
Python
# Copyright (c) 2017 Johns Hopkins University Applied Physics Laboratory
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from oslo_log import log as logging
|
|
from tempest.api.compute import base as compute_base
|
|
from tempest.common import utils
|
|
from tempest import config
|
|
from tempest import exceptions
|
|
from tempest.lib import decorators
|
|
|
|
from barbican_tempest_plugin.tests.scenario import barbican_manager
|
|
|
|
CONF = config.CONF
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class ImageSigningTest(barbican_manager.BarbicanScenarioTest):
|
|
|
|
@decorators.idempotent_id('4343df3c-5553-40ea-8705-0cce73b297a9')
|
|
@utils.services('compute', 'image')
|
|
def test_signed_image_upload_and_boot(self):
|
|
"""Test that Nova boots a signed image.
|
|
|
|
The test follows these steps:
|
|
* Create an asymmetric keypair
|
|
* Sign an image file with the private key
|
|
* Create a certificate with the public key
|
|
* Store the certificate in Barbican
|
|
* Store the signed image in Glance
|
|
* Boot the signed image
|
|
* Confirm the instance changes state to Active
|
|
"""
|
|
img_uuid = self.sign_and_upload_image()
|
|
|
|
LOG.debug("Booting server with signed image %s", img_uuid)
|
|
instance = self.create_server(name='signed_img_server',
|
|
image_id=img_uuid,
|
|
wait_until='ACTIVE')
|
|
self.servers_client.delete_server(instance['id'])
|
|
|
|
@decorators.idempotent_id('74f022d6-a6ef-4458-96b7-541deadacf99')
|
|
@utils.services('compute', 'image')
|
|
def test_signed_image_upload_boot_failure(self):
|
|
"""Test that Nova refuses to boot an incorrectly signed image.
|
|
|
|
If the create_server call succeeds instead of throwing an
|
|
exception, it is likely that signature verification is not
|
|
turned on. To turn on signature verification, set
|
|
verify_glance_signatures=True in the nova configuration
|
|
file under the [glance] section.
|
|
|
|
The test follows these steps:
|
|
* Create an asymmetric keypair
|
|
* Sign an image file with the private key
|
|
* Create a certificate with the public key
|
|
* Store the certificate in Barbican
|
|
* Store the signed image in Glance
|
|
* Modify the signature to be incorrect
|
|
* Attempt to boot the incorrectly signed image
|
|
* Confirm an exception is thrown
|
|
"""
|
|
img_uuid = self.sign_and_upload_image()
|
|
|
|
LOG.debug("Modifying image signature to be incorrect")
|
|
metadata = {'img_signature': 'fake_signature'}
|
|
self.compute_images_client.update_image_metadata(
|
|
img_uuid, metadata
|
|
)
|
|
|
|
self.assertRaisesRegex(exceptions.BuildErrorException,
|
|
"Signature verification for the image failed",
|
|
self.create_server,
|
|
image_id=img_uuid)
|
|
|
|
|
|
class ImageSigningSnapshotTest(barbican_manager.BarbicanScenarioTest,
|
|
compute_base.BaseV2ComputeTest):
|
|
|
|
@classmethod
|
|
def setup_clients(cls):
|
|
super(ImageSigningSnapshotTest, cls).setup_clients()
|
|
cls.client = cls.servers_client
|
|
|
|
@decorators.idempotent_id('f0603dfd-8b2c-44e2-8b0f-d65c87aab257')
|
|
@utils.services('compute', 'image')
|
|
def test_signed_image_upload_boot_snapshot(self):
|
|
"""Test that Glance can snapshot an instance using a signed image.
|
|
|
|
Verify that a snapshot can be taken of an instance booted from a signed
|
|
image and that the resulting snapshot image has had all image signature
|
|
properties dropped from the original image.
|
|
|
|
The test follows these steps:
|
|
* Create an asymmetric keypair
|
|
* Sign an image file with the private key
|
|
* Create a certificate with the public key
|
|
* Store the certificate in Barbican
|
|
* Store the signed image in Glance
|
|
* Boot the signed image
|
|
* Confirm the instance changes state to Active
|
|
* Snapshot the running instance
|
|
* Uploading the snapshot and confirm the state moves to ACTIVE
|
|
"""
|
|
img_uuid = self.sign_and_upload_image()
|
|
instance = self.create_server(name='signed_img_server_to_snapshot',
|
|
image_id=img_uuid,
|
|
wait_until='ACTIVE')
|
|
|
|
# Snapshot the instance, wait until the snapshot is active
|
|
image = self.create_image_from_server(instance['id'],
|
|
wait_until='ACTIVE')
|
|
|
|
# Ensure all img_signature image props have been dropped
|
|
signature_props = ['img_signature_hash_method',
|
|
'img_signature',
|
|
'img_signature_key_type',
|
|
'img_signature_certificate_uuid']
|
|
img_meta = self.compute_images_client.list_image_metadata(image['id'])
|
|
self.assertFalse(any(x in img_meta for x in signature_props))
|
|
|
|
self.servers_client.delete_server(instance['id'])
|