Register client and add first test

Add first API test and register the client with
the new tempest.lib client interface.

Change-Id: I27f15375c46faa48cd56c8d52ecfd585fb325239
Implements: bp tempest-plugin
This commit is contained in:
Marc Koderer 2016-12-12 11:49:10 +01:00 committed by dane-fichter
parent 3529ea7a43
commit c832c613fa
8 changed files with 235 additions and 0 deletions

View File

@ -0,0 +1,32 @@
# Copyright (c) 2016 SAP SE
#
# 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 tempest import config
from tempest.lib.services import clients
CONF = config.CONF
class Clients(clients.ServiceClients):
"""Tempest stable service clients and loaded plugins service clients"""
def __init__(self, credentials, service=None):
"""Emulate the interface of Tempest's clients.Manager"""
# Identity settings
if CONF.identity.auth_version == 'v2':
identity_uri = CONF.identity.uri
else:
identity_uri = CONF.identity.uri_v3
super(Clients, self).__init__(credentials, identity_uri)

View File

@ -35,3 +35,12 @@ class BarbicanTempestPlugin(plugins.TempestPlugin):
def get_opt_lists(self):
return [('service_available', [project_config.service_option])]
def get_service_clients(self):
v1_params = {
'name': 'secret_v1',
'service_version': 'secret.v1',
'module_path': 'barbican_tempest_plugin.services.key_manager.json',
'client_names': ['SecretClient'],
}
return [v1_params]

View File

@ -0,0 +1,18 @@
# Copyright (c) 2016 SAP SE
#
# 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 barbican_tempest_plugin.services.key_manager.json.secret_client import \
SecretClient
__all__ = ['SecretClient']

View File

@ -0,0 +1,40 @@
# Copyright 2016 SAP SE
# All Rights Reserved.
#
# 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.
import json
from tempest import config
from tempest.lib.common import rest_client
from tempest.lib.common.utils import data_utils
CONF = config.CONF
class SecretClient(rest_client.RestClient):
def create_secret(self, **kwargs):
if 'name' not in kwargs:
kwargs['name'] = data_utils.rand_name("tempest-sec")
post_body = kwargs
body = json.dumps(post_body)
resp, body = self.post("v1/secrets", body)
self.expected_success(201, resp.status)
return self._parse_resp(body)
def delete_secret(self, secret_id):
resp, body = self.delete("v1/secrets/%s" % secret_id)
self.expected_success(204, resp.status)
return body

View File

@ -0,0 +1,84 @@
# Copyright 2016 SAP SE
# All Rights Reserved.
#
# 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.
import functools
from tempest import config
from tempest import test
from barbican_tempest_plugin import clients
CONF = config.CONF
# NOTE(dane-fichter): We need to track resource types for cleanup.
RESOURCE_TYPES = ['secret']
def _get_uuid(href):
return href.split('/')[-1]
def creates(resource):
"""Decorator that adds resource UUIDs to queue for cleanup"""
def decorator(f):
@functools.wraps(f)
def wrapper(cls, *args, **kwargs):
resp = f(cls, *args, **kwargs)
if resource == 'secret':
uuid = _get_uuid(resp['secret_ref'])
cls.created_objects[resource].add(uuid)
return resp
return wrapper
return decorator
class BaseKeyManagerTest(test.BaseTestCase):
"""Base class for all api tests."""
# Why do I have to be an admin to create secrets? No idea...
credentials = ('admin', )
client_manager = clients.Clients
created_objects = {}
@classmethod
def setup_clients(cls):
super(BaseKeyManagerTest, cls).setup_clients()
os = getattr(cls, 'os_%s' % cls.credentials[0])
cls.secret_client = os.secret_v1.SecretClient(service='key-manager')
@classmethod
def resource_setup(cls):
super(BaseKeyManagerTest, cls).resource_setup()
for resource in RESOURCE_TYPES:
cls.created_objects[resource] = set()
@classmethod
def resource_cleanup(cls):
try:
for secret_uuid in cls.created_objects['secret']:
cls.delete_secret(secret_uuid)
finally:
super(BaseKeyManagerTest, cls).resource_cleanup()
@classmethod
@creates('secret')
def create_secret(cls, **kwargs):
return cls.secret_client.create_secret(**kwargs)
@classmethod
def delete_secret(cls, uuid):
cls.created_objects['secret'].remove(uuid)
return cls.secret_client.delete_secret(uuid)

View File

@ -0,0 +1,51 @@
# Copyright 2016 SAP SE
# All Rights Reserved.
#
# 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.
import base64
from datetime import datetime
from datetime import timedelta
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from barbican_tempest_plugin.tests.api import base
class SecretsTest(base.BaseKeyManagerTest):
"""Secrets API tests."""
def test_create_delete_empty_secret(self):
sec = self.create_secret()
uuid = base._get_uuid(sec['secret_ref'])
self.delete_secret(uuid)
def test_create_delete_symmetric_key(self):
password = b"password"
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(), length=32, salt=salt,
iterations=1000, backend=default_backend()
)
key = base64.b64encode(kdf.derive(password))
expire_time = (datetime.utcnow() + timedelta(days=5))
sec = self.create_secret(
expiration=expire_time.isoformat(), algorithm="aes",
bit_length=256, mode="cbc", payload=key,
payload_content_type="application/octet-stream",
payload_content_encoding="base64"
)
uuid = base._get_uuid(sec['secret_ref'])
self.delete_secret(uuid)

View File

@ -6,3 +6,4 @@ pbr>=1.8 # Apache-2.0
tempest>=12.1.0 # Apache-2.0
tempest-lib>=0.14.0 # Apache-2.0
cryptography!=1.3.0,>=1.0 # BSD/Apache-2.0