From 993adb74b40de64ef62518c009c3b4b86ec76fd9 Mon Sep 17 00:00:00 2001 From: Charles Short Date: Tue, 8 Jan 2019 16:44:48 +0000 Subject: [PATCH] Add barbican scenario for symmetric secret Add BarbicanSecrets.create_symmetric_and_delete scenario to create a symmetric secret. User can specify payload, algorithm, bit_length, and mode used for the scenario. Change-Id: I5c5ca847f8b96de94654e16c37e11437e462c3f6 Signed-off-by: Charles Short --- CHANGELOG.rst | 26 +++++++++----- rally-jobs/barbican.yaml | 8 +++-- rally_openstack/scenarios/barbican/secrets.py | 36 +++++++++++++++++++ .../services/key_manager/barbican.py | 30 +++++++++++++--- .../create-and-delete-symmetric-secret.json | 28 +++++++++++++++ .../create-and-delete-symmetric-secret.yaml | 20 +++++++++++ tests/unit/scenarios/barbican/test_secrets.py | 9 +++++ 7 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.json create mode 100644 samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.yaml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fbadfb88..815ae4b5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -29,15 +29,23 @@ Added * [scenario plugin] BarbicanContainers.create_and_add * [scenario plugin] BarbicanContainers.create_certificate_and_delete * [scenario plugin] BarbicanContainers.create_rsa_and_delete -* [scenario plugin] Octavia.create_and_list_loadbalancers -* [scenario plugin] Octavia.create_and_delete_loadbalancers -* [scenario plugin] Octavia.create_and_update_loadbalancers -* [scenario plugin] Octavia.create_and_stats_loadbalancers -* [scenario plugin] Octavia.create_and_show_loadbalancers -* [scenario plugin] Octavia.create_and_list_pools -* [scenario plugin] Octavia.create_and_delete_pools -* [scenario plugin] Octavia.create_and_update_pools -* [scenario plugin] Octavia.create_and_show_pools + * [scenario plugin] BarbicanSecrets.list + * [scenario plugin] BarbicanSecrets.create + * [scenario plugin] BarbicanSecrets.create_and_delete + * [scenario plugin] BarbicanSecrets.create_and_get + * [scenario plugin] BarbicanSecrets.get + * [scenario plugin] BarbicanSecrets.create_and_list + * [scenario plugin] BarbicanSecrets.create_symmetric_and_delete +* Added octavia scenarios + * [scenario plugin] Octavia.create_and_list_loadbalancers + * [scenario plugin] Octavia.create_and_delete_loadbalancers + * [scenario plugin] Octavia.create_and_update_loadbalancers + * [scenario plugin] Octavia.create_and_stats_loadbalancers + * [scenario plugin] Octavia.create_and_show_loadbalancers + * [scenario plugin] Octavia.create_and_list_pools + * [scenario plugin] Octavia.create_and_delete_pools + * [scenario plugin] Octavia.create_and_update_pools + * [scenario plugin] Octavia.create_and_show_pools * Support for osprofiler config in Devstack plugin. * Added property 'floating_ip_enabled' in magnum cluster_templates context. * Enhanced neutron trunk port scenario to create multiple trunks diff --git a/rally-jobs/barbican.yaml b/rally-jobs/barbican.yaml index 6341edba..6d3da0a7 100644 --- a/rally-jobs/barbican.yaml +++ b/rally-jobs/barbican.yaml @@ -130,11 +130,15 @@ tenants: 1 users_per_tenant: 1 - - title: BarbicanContainers.create_and_add + title: BarbicanSecrets.create_symmetric_and_delete workloads: - scenario: - BarbicanContainers.create_and_add: {} + BarbicanSecrets.create_symmetric_and_delete: + payload: "rally_data" + algorithm: "aes" + bit_length: 256 + mode: "cbc" runner: constant: times: 2 diff --git a/rally_openstack/scenarios/barbican/secrets.py b/rally_openstack/scenarios/barbican/secrets.py index deb32954..c5853948 100644 --- a/rally_openstack/scenarios/barbican/secrets.py +++ b/rally_openstack/scenarios/barbican/secrets.py @@ -12,6 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. +import base64 +import datetime as dt +import os + from rally.task import validation from rally_openstack import consts @@ -90,3 +94,35 @@ class BarbicanSecretsCreateAndList(utils.BarbicanBase): """Create and then list all secrets.""" self.admin_barbican.create_secret() self.admin_barbican.list_secrets() + + +@validation.add("required_services", services=[consts.Service.BARBICAN]) +@validation.add("required_platform", platform="openstack", admin=True) +@scenario.configure(context={"admin_cleanup@openstack": ["barbican"]}, + name="BarbicanSecrets.create_symmetric_and_delete") +class BarbicanSecretsCreateSymmetricAndDelete(utils.BarbicanBase): + def run(self, payload, algorithm, bit_length, mode): + """Create and delete symmetric secret + + :param payload: The unecrypted data + :param algorithm: the algorithm associated with the secret key + :param bit_length: the big length of the secret key + :param mode: the algorithm mode used with the secret key + """ + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC + + payload = payload.encode("utf-8") + salt = os.urandom(16) + kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), length=32, salt=salt, + iterations=1000, backend=default_backend()) + payload = base64.b64encode(kdf.derive(payload)) + expire_time = (dt.datetime.utcnow() + dt.timedelta(days=5)) + secret = self.admin_barbican.create_secret( + expiration=expire_time.isoformat(), algorithm=algorithm, + bit_length=bit_length, mode=mode, payload=payload, + payload_content_type="application/octet-stream", + payload_content_encoding="base64") + self.admin_barbican.delete_secret(secret.secret_ref) diff --git a/rally_openstack/services/key_manager/barbican.py b/rally_openstack/services/key_manager/barbican.py index 6cf3e7a7..4a1db8d1 100644 --- a/rally_openstack/services/key_manager/barbican.py +++ b/rally_openstack/services/key_manager/barbican.py @@ -24,11 +24,31 @@ class BarbicanService(service.Service): return self._clients.barbican().secrets.list() @atomic.action_timer("barbican.create_secret") - def create_secret(self): - """Create Secret""" - secret_name = self.generate_random_name() - val = self._clients.barbican().secrets.create(name=secret_name, - payload="rally_data") + def create_secret(self, name=None, payload=None, + payload_content_type=None, payload_content_encoding=None, + algorithm=None, bit_length=None, secret_type=None, + mode=None, expiration=None): + """Create Secret + + :param name: A friendly name for the secret + :param payload: The unecrypted secret data + :param payload_content_type: the format/type of the secret data + :param payload_content_encoding: the encoding of the secret data + :param algorithm: the algorithm associated with this secret key + :param bit_length: The bit length of this secret key + :param mode: the algorigthm mode used with this secret key + :param secret_type: The secret type for this secret key + :param exipration: the expiration time of the secret in ISO8601 + format + :returns: a new secret object + """ + name = name or self.generate_random_name() + val = self._clients.barbican().secrets.create( + name=name, payload=payload, + payload_content_type=payload_content_type, + payload_content_encoding=payload_content_encoding, + algorithm=algorithm, bit_length=bit_length, mode=mode, + secret_type=secret_type, expiration=expiration) val.store() return val diff --git a/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.json b/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.json new file mode 100644 index 00000000..464bed64 --- /dev/null +++ b/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.json @@ -0,0 +1,28 @@ +{ + "BarbicanSecrets.create_symmetric_and_delete": [ + { + "args": { + "payload": "rally_data", + "algorithm": "aes", + "bit_length": 256, + "mode": "cbc" + }, + "runner": { + "type": "constant", + "times": 2, + "concurrency": 1 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.yaml b/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.yaml new file mode 100644 index 00000000..b1ab1af4 --- /dev/null +++ b/samples/tasks/scenarios/barbican/create-and-delete-symmetric-secret.yaml @@ -0,0 +1,20 @@ +--- + BarbicanSecrets.create_symmetric_and_delete: + - + args: + payload: "rally_data" + algorithm: "aes" + bit_length: 256 + mode: "cbc" + runner: + type: "constant" + times: 2 + concurrency: 1 + context: + users: + tenants: 1 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + diff --git a/tests/unit/scenarios/barbican/test_secrets.py b/tests/unit/scenarios/barbican/test_secrets.py index 753441b2..8d32b182 100644 --- a/tests/unit/scenarios/barbican/test_secrets.py +++ b/tests/unit/scenarios/barbican/test_secrets.py @@ -97,3 +97,12 @@ class BarbicanSecretsTestCase(test.ScenarioTestCase): scenario.run() secrets_service.create_secret.assert_called_once_with() secrets_service.list_secrets.assert_called_once_with() + + def test_create_and_delete_symmetric_secret(self): + secrets_service = self.mock_secrets.return_value + scenario = secrets.BarbicanSecretsCreateSymmetricAndDelete( + self.context) + scenario.run( + payload="rally_data", algorithm="aes", bit_length=256, + mode="cbc") + self.assertEqual(1, secrets_service.create_secret.call_count)