diff --git a/barbican_tempest_plugin/config.py b/barbican_tempest_plugin/config.py index 4326351..eae7a17 100644 --- a/barbican_tempest_plugin/config.py +++ b/barbican_tempest_plugin/config.py @@ -19,3 +19,27 @@ service_option = cfg.BoolOpt("barbican", default=True, help="Whether or not barbican is expected to be " "available") + +ephemeral_storage_encryption_group = cfg.OptGroup( + name="ephemeral_storage_encryption", + title="Ephemeral storage encryption options") + +EphemeralStorageEncryptionGroup = [ + cfg.BoolOpt('enabled', + default=False, + help="Does the test environment support ephemeral storage " + "encryption?"), + cfg.StrOpt('cipher', + default='aes-xts-plain64', + help="The cipher and mode used to encrypt ephemeral storage. " + "AES-XTS is recommended by NIST specifically for disk " + "storage, and the name is shorthand for AES encryption " + "using the XTS encryption mode. Available ciphers depend " + "on kernel support. At the command line, type " + "'cryptsetup benchmark' to determine the available " + "options (and see benchmark results), or go to " + "/proc/crypto."), + cfg.IntOpt('key_size', + default=256, + help="The key size used to encrypt ephemeral storage."), +] diff --git a/barbican_tempest_plugin/plugin.py b/barbican_tempest_plugin/plugin.py index 2c13b24..a586eb0 100644 --- a/barbican_tempest_plugin/plugin.py +++ b/barbican_tempest_plugin/plugin.py @@ -33,6 +33,11 @@ class BarbicanTempestPlugin(plugins.TempestPlugin): conf.register_opt(project_config.service_option, group='service_available') + # Register ephemeral storage encryption options + conf.register_group(project_config.ephemeral_storage_encryption_group) + conf.register_opts(project_config.EphemeralStorageEncryptionGroup, + project_config.ephemeral_storage_encryption_group) + def get_opt_lists(self): return [('service_available', [project_config.service_option])] diff --git a/barbican_tempest_plugin/tests/scenario/test_ephemeral_disk_encryption.py b/barbican_tempest_plugin/tests/scenario/test_ephemeral_disk_encryption.py new file mode 100644 index 0000000..0dc78a9 --- /dev/null +++ b/barbican_tempest_plugin/tests/scenario/test_ephemeral_disk_encryption.py @@ -0,0 +1,65 @@ +# 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 import config +from tempest.lib import decorators +from tempest import test + +from barbican_tempest_plugin.tests.scenario import barbican_manager + +CONF = config.CONF +LOG = logging.getLogger(__name__) + + +class EphemeralStorageEncryptionTest(barbican_manager.BarbicanScenarioTest): + + """The test suite for encrypted ephemeral storage + + This test verifies the functionality of encrypted ephemeral storage. + This test performs the following: + * Creates an image in Glance + * Boots an instance from the image + * Writes to a new file in the instance + """ + + @classmethod + def skip_checks(cls): + super(EphemeralStorageEncryptionTest, cls).skip_checks() + if not CONF.ephemeral_storage_encryption.enabled: + raise cls.skipException( + 'Ephemeral storage encryption is not supported') + + @decorators.idempotent_id('afe720b9-8b35-4a3c-8ff3-15841c2d3148') + @test.services('compute', 'image') + def test_encrypted_ephemeral_lvm_storage(self): + test_string = 'Once upon a time ...' + client_test_path = '/tmp/ephemeral_disk_encryption_test' + img_uuid = self.sign_and_upload_image() + keypair = self.create_keypair() + security_group = self._create_security_group() + instance = self.create_server( + name='signed_img_server', + image_id=img_uuid, + key_name=keypair['name'], + security_groups=[{'name': security_group['name']}], + wait_until='ACTIVE') + instance_ip = self.get_server_ip(instance) + ssh_client = self.get_remote_client( + instance_ip, + private_key=keypair['private_key']) + ssh_client.exec_command('echo "%s" > %s' % (test_string, + client_test_path)) + test_output = ssh_client.exec_command('cat %s' % client_test_path) + self.assertEqual(str(test_string), str(test_output.rstrip())) diff --git a/tools/pre_test_hook.sh b/tools/pre_test_hook.sh index 2640433..63b123e 100755 --- a/tools/pre_test_hook.sh +++ b/tools/pre_test_hook.sh @@ -11,11 +11,22 @@ export LOCALCONF_PATH=$DEVSTACK_DIR/local.conf # Here we can set some configurations for local.conf # for example, to pass some config options directly to .conf files +# Set up LVM device +echo -e '[[local|localrc]]' >> $LOCALCONF_PATH +echo -e 'NOVA_BACKEND=LVM' >> $LOCALCONF_PATH +echo -e 'LVM_VOLUME_CLEAR=none' >> $LOCALCONF_PATH + # For image signature verification tests echo -e '[[post-config|$NOVA_CONF]]' >> $LOCALCONF_PATH echo -e '[glance]' >> $LOCALCONF_PATH echo -e 'verify_glance_signatures = True' >> $LOCALCONF_PATH +# For ephemeral storage encryption tests +echo -e '[ephemeral_storage_encryption]' >> $LOCALCONF_PATH +echo -e 'key_size = 256' >> $LOCALCONF_PATH +echo -e 'cipher = aes-xts-plain64' >> $LOCALCONF_PATH +echo -e 'enabled = True' >> $LOCALCONF_PATH + # Allow dynamically created tempest users to create secrets # in barbican echo -e '[[test-config|$TEMPEST_CONFIG]]' >> $LOCALCONF_PATH @@ -24,3 +35,7 @@ echo -e 'tempest_roles=creator' >> $LOCALCONF_PATH # Glance v1 doesn't do signature verification on image upload echo -e '[image-feature-enabled]' >> $LOCALCONF_PATH echo -e 'api_v1=False' >> $LOCALCONF_PATH + +# Enable ephemeral storage encryption in Tempest +echo -e '[ephemeral_storage_encryption]' >> $LOCALCONF_PATH +echo -e 'enabled = True' >> $LOCALCONF_PATH