Add barbican scenarios

Added code to test barbican scenarios. These
scenarios include the following:

- create and delete secret
- create and get secret
- create and list secret
- create secret
- list secrets

Also add the assoicated zuul and rally-jobs for openstack CI
test infrastructure.

Change-Id: I378666e026200c020cd8d25ebb5b669644c4a364
Signed-off-by: Chuck Short <chucks@redhat.com>
This commit is contained in:
Chuck Short 2018-09-17 13:32:38 -04:00 committed by Andrey Kurilin
parent 81ab47030e
commit 7631da2425
29 changed files with 751 additions and 0 deletions

View File

@ -0,0 +1,27 @@
- job:
name: rally-task-barbican
parent: rally-task-at-devstack
required-projects:
- name: openstack-dev/devstack
- name: openstack-infra/devstack-gate
- name: openstack/rally
- name: openstack/rally-openstack
- name: openstack/barbican
- name: openstack/python-barbicanclient
vars:
devstack_plugins:
rally-openstack: https://git.openstack.org/openstack/rally-openstack
barbican: https://git.openstack.org/openstack/barbican
devstack_services:
barbican: true
# disable redundant services for the job
ceilometer-acentral: false
ceilometer-acompute: false
ceilometer-alarm-evaluator: false
ceilometer-alarm-notifier: false
ceilometer-anotification: false
ceilometer-api: false
ceilometer-collector: false
horizon: false
tempest: false
rally_task: rally-jobs/barbican.yaml

View File

@ -54,6 +54,8 @@
- rally-task-basic-with-existing-users:
# use_existing_users key did not trigger proper ansible tasks
voting: false
- rally-task-barbican:
voting: false
- rally-task-cinder
# NOTE(andreykurilin): this requires more thing to configure before
# launching.

View File

@ -23,6 +23,7 @@ Added
~~~~~
* Added neutron trunk scenarios
* Added barbican scenarios.
[1.3.0] - 2018-10-08
--------------------

75
rally-jobs/barbican.yaml Normal file
View File

@ -0,0 +1,75 @@
---
version: 2
title: Task for rally-task-barbican-job
description: Testing just one cinder scenario to verify that rally-task-barbican works
subtasks:
-
title: BarbicanSecrets.create_and_delete
workloads:
-
scenario:
BarbicanSecrets.create_and_delete: {}
runner:
constant:
times: 2
concurrency: 1
contexts:
users:
tenants: 1
users_per_tenant: 1
-
title: BarbicanSecrets.get
workloads:
-
scenario:
BarbicanSecrets.get: {}
runner:
constant:
times: 2
concurrency: 1
contexts:
users:
tenants: 1
users_per_tenant: 1
-
title: BarbicanSecrets.create_and_list
workloads:
-
scenario:
BarbicanSecrets.create_and_list: {}
runner:
constant:
times: 2
concurrency: 1
contexts:
users:
tenants: 1
users_per_tenant: 1
-
title: BarbicanSecrets.create
workloads:
-
scenario:
BarbicanSecrets.create: {}
runner:
constant:
times: 2
concurrency: 1
contexts:
users:
tenants: 1
users_per_tenant: 1
-
title: BarbicanSecrets.list
workloads:
-
scenario:
BarbicanSecrets.list: {}
runner:
constant:
times: 2
concurrency: 1
contexts:
users:
tenants: 1
users_per_tenant: 1

View File

@ -524,6 +524,7 @@ class CinderQos(base.ResourceManager):
# MANILA
_manila_order = get_order(450)
@ -814,6 +815,7 @@ class MistralExecutions(SynchronizedDeletion, base.ResourceManager):
# MURANO
_murano_order = get_order(1200)
@ -1041,3 +1043,21 @@ class KeystoneEc2(SynchronizedDeletion, base.ResourceManager):
def delete(self):
self._manager().delete_ec2credential(
self.user_id, access=self.raw_resource.access)
# BARBICAN
@base.resource("barbican", "secrets", order=1500, admin_required=True,
perform_for_admin_only=True)
class BarbicanSecrets(base.ResourceManager):
def id(self):
return self.raw_resource.secret_ref
def is_deleted(self):
try:
self._manager().get(self.id())
except Exception:
return True
return False

View File

@ -67,6 +67,7 @@ class _Service(utils.ImmutableMixin, utils.EnumMixin):
GNOCCHI = "gnocchi"
MAGNUM = "magnum"
WATCHER = "watcher"
BARBICAN = "barbican"
class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
@ -98,6 +99,7 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
METRIC = "metric"
CONTAINER_INFRA = "container-infra"
INFRA_OPTIM = "infra-optim"
KEY_MANAGER = "key-manager"
def __init__(self):
self.__names = {
@ -127,6 +129,7 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
self.METRIC: _Service.GNOCCHI,
self.CONTAINER_INFRA: _Service.MAGNUM,
self.INFRA_OPTIM: _Service.WATCHER,
self.KEY_MANAGER: _Service.BARBICAN
}
def __getitem__(self, service_type):

View File

@ -0,0 +1,105 @@
# Copyright 2018 Red Hat, Inc. <http://www.redhat.com>
#
# 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 rally.task import validation
from rally_openstack import consts
from rally_openstack import scenario
from rally_openstack.services.key_manager import barbican
"""Scenarios for Barbican secrets."""
class BarbicanBase(scenario.OpenStackScenario):
"""Base class for Barbican scenarios with basic atomic actions."""
def __init__(self, context=None, admin_context=None, clients=None):
super(BarbicanBase, self).__init__(context, admin_context, clients)
if hasattr(self, "_admin_clients"):
self.admin_barbican = barbican.BarbicanService(
self._admin_clients, name_generator=self.generate_random_name,
atomic_inst=self.atomic_actions())
@validation.add("required_services", services=[consts.Service.BARBICAN])
@validation.add("required_platform", platform="openstack", admin=True)
@scenario.configure(name="BarbicanSecrets.list")
class BarbicanSecretsList(BarbicanBase):
def run(self):
"""List secrets."""
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")
class BarbicanSecretsCreate(BarbicanBase):
def run(self):
"""Create secret."""
self.admin_barbican.create_secret()
@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_and_delete")
class BarbicanSecretsCreateAndDelete(BarbicanBase):
def run(self):
"""Create and Delete secret."""
secret = self.admin_barbican.create_secret()
self.admin_barbican.delete_secret(secret.secret_ref)
@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_and_get")
class BarbicanSecretsCreateAndGet(BarbicanBase):
def run(self):
"""Create and Get Secret.
"""
secret = self.admin_barbican.create_secret()
self.assertTrue(secret)
secret_info = self.admin_barbican.get_secret(secret.secret_ref)
self.assertEqual(secret.secret_ref, secret_info.secret_ref)
@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.get")
class BarbicanSecretsGet(BarbicanBase):
def run(self, secret_ref=None):
"""Create and Get Secret.
:param secret_ref: Name of the secret to get
"""
if secret_ref is None:
secret = self.admin_barbican.create_secret()
self.admin_barbican.get_secret(secret.secret_ref)
else:
self.admin_barbican.get_secret(secret_ref)
@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_and_list")
class BarbicanSecretsCreateAndList(BarbicanBase):
def run(self):
"""Create and then list all secrets."""
self.admin_barbican.create_secret()
self.admin_barbican.list_secrets()

View File

@ -0,0 +1,49 @@
# Copyright 2018 Red Hat, Inc. <http://www.redhat.com>
#
# 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 rally.task import atomic
from rally.task import service
class BarbicanService(service.Service):
@atomic.action_timer("barbican.list_secrets")
def list_secrets(self):
"""List Secret"""
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")
val.store()
return val
@atomic.action_timer("barbican.get_secret")
def get_secret(self, secret_ref):
"""Get the secret.
:param secret_name: The name of the secret.
"""
return self._clients.barbican().secrets.get(secret_ref)
@atomic.action_timer("barbican.delete_secret")
def delete_secret(self, secret_name):
"""Delete the secret
:param secret_name: The name of the secret to delete
"""
return self._clients.barbican().secrets.delete(secret_name)

View File

@ -13,6 +13,7 @@ keystoneauth1>=3.3.0 # Apache Software License
kubernetes>1.0.0 # Apache License Version 2.0
os-faults>=0.1.15 # Apache Software License
osprofiler>=1.4.0 # Apache Software License
python-barbicanclient>=4.5.2 # Apache Software License
python-ceilometerclient>=2.5.0 # Apache Software License
python-cinderclient>=3.3.0 # Apache Software License
python-designateclient>=2.7.0 # Apache License, Version 2.0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.create_and_delete": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.create_and_delete:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.create_and_get": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.create_and_get:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.create_and_list": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.create_and_list:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.create": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.create:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.get": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.get:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,22 @@
{
"BarbicanSecrets.list": [
{
"runner": {
"type": "constant",
"times": 2,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
BarbicanSecrets.list:
-
runner:
type: "constant"
times: 2
concurrency: 1
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -1170,3 +1170,32 @@ class GnocchiResourceTestCase(test.TestCase):
[mock.call(marker=None), mock.call(marker=res[1]["id"]),
mock.call(marker=res[3]["id"])],
gnocchi._manager.return_value.list.call_args_list)
class BarbicanSecretsTestCase(test.TestCase):
def test_id(self):
barbican = resources.BarbicanSecrets()
barbican.raw_resource = mock.MagicMock(secret_ref="fake_uuid")
self.assertEqual("fake_uuid", barbican.id())
def test_list(self):
barbican = resources.BarbicanSecrets()
barbican._manager = mock.MagicMock()
barbican.list()
barbican._manager.assert_called_once_with()
def test_delete(self):
barbican = resources.BarbicanSecrets()
barbican._manager = mock.MagicMock()
barbican.raw_resource = mock.MagicMock(uuid="fake_uuid")
barbican.delete()
barbican._manager.assert_called_once_with()
def test_is_deleted(self):
barbican = resources.BarbicanSecrets()
barbican._manager = mock.MagicMock()
barbican.raw_resource = mock.MagicMock(uuid="fake_uuid")
self.assertFalse(barbican.is_deleted())

View File

@ -187,6 +187,14 @@ class FakeFlavor(FakeResource):
self.name = name
class FakeSecret(FakeResource):
def __init__(self, id="secret-id-0", manager=None, secret_ref="secret_ref",
name="secret-name-0"):
super(FakeSecret, self).__init__(manager, id=id)
self.secret_ref = secret_ref
class FakeKeypair(FakeResource):
pass

View File

@ -0,0 +1,99 @@
# Copyright 2018 Red Hat Inc
# 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 mock
from rally_openstack.scenarios.barbican import secrets
from tests.unit import fakes
from tests.unit import test
class BarbicanSecretsTestCase(test.ScenarioTestCase):
def get_test_context(self):
context = super(BarbicanSecretsTestCase, self).get_test_context()
context.update({
"admin": {
"user_id": "fake",
"credential": mock.MagicMock()
},
"user": {
"user_id": "fake",
"credential": mock.MagicMock()
},
"tenant": {"id": "fake"}
})
return context
def setUp(self):
super(BarbicanSecretsTestCase, self).setUp()
patch = mock.patch(
"rally_openstack.services.key_manager.barbican.BarbicanService")
self.addCleanup(patch.stop)
self.mock_secrets = patch.start()
def test_list_secrets(self):
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsList(self.context)
scenario.run()
secrets_service.list_secrets.assert_called_once_with()
def test_create_secret(self):
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsCreate(self.context)
scenario.run()
secrets_service.create_secret.assert_called_once_with()
def test_create_and_delete_secret(self):
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsCreateAndDelete(self.context)
scenario.run()
secrets_service.create_secret.assert_called_once_with()
self.assertEqual(1, secrets_service.delete_secret.call_count)
def test_create_and_get_secret(self):
secrets_service = self.mock_secrets.return_value
fake_secret = fakes.FakeSecret(id=1, name="secretxxx")
secrets_service.create_secret.return_value = fake_secret
fake_secret_info = fakes.FakeSecret(id=1, name="secret1xxx")
secrets_service.get_secret.return_value = fake_secret_info
scenario = secrets.BarbicanSecretsCreateAndGet(self.context)
scenario.run()
secrets_service.create_secret.assert_called_once_with()
def test_get_secret(self):
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsGet(self.context)
scenario.run()
secrets_service.create_secret.assert_called_once_with()
def test_get_secret_with_secret(self):
secret = mock.Mock()
secret.secret_ref = mock.Mock()
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsGet(self.context)
scenario.run()
self.assertEqual(1, secrets_service.get_secret.call_count)
def test_create_and_list_secret(self):
secrets_service = self.mock_secrets.return_value
scenario = secrets.BarbicanSecretsCreateAndList(self.context)
scenario.run()
secrets_service.create_secret.assert_called_once_with()
secrets_service.list_secrets.assert_called_once_with()

View File

@ -0,0 +1,47 @@
# Copyright 2018 Red Hat Inc
# 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 mock
from rally_openstack.scenarios.barbican import secrets
from tests.unit import test
class BarbicanBaseTestCase(test.ScenarioTestCase):
def setUp(self):
super(BarbicanBaseTestCase, self).setUp()
self.context = super(BarbicanBaseTestCase, self).get_test_context()
self.context.update({
"admin": {
"id": "fake_user_id",
"credential": mock.MagicMock()
},
"user": {
"id": "fake_user_id",
"credential": mock.MagicMock()
},
"tenant": {"id": "fake_tenant_id",
"name": "fake_tenant_name"}
})
patch = mock.patch(
"rally_openstack.services.key_manager.barbican.BarbicanService")
self.addCleanup(patch.stop)
self.mock_service = patch.start()
def test_barbican_base(self):
base = secrets.BarbicanBase(self.context)
self.assertEqual(base.admin_barbican,
self.mock_service.return_value)

View File

View File

@ -0,0 +1,62 @@
# Copyright 2018 Red Hat, Inc. <http://www.redhat.com>
#
# 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 mock
from rally_openstack.services.key_manager import barbican
from tests.unit import test
class BarbicanServiceTestCase(test.TestCase):
def setUp(self):
super(BarbicanServiceTestCase, self).setUp()
self.clients = mock.MagicMock()
self.name_generator = mock.MagicMock()
self.service = barbican.BarbicanService(
self.clients,
name_generator=self.name_generator)
def atomic_actions(self):
return self.service._atomic_actions
def test__list_secrets(self):
self.assertEqual(
self.service.list_secrets(),
self.service._clients.barbican().secrets.list.return_value
)
self._test_atomic_action_timer(self.atomic_actions(),
"barbican.list_secrets")
def test__create_secret(self):
self.assertEqual(
self.service.create_secret(),
self.service._clients.barbican().secrets.create(
name="fake_secret", payload="rally_data")
)
self._test_atomic_action_timer(self.atomic_actions(),
"barbican.create_secret")
def test__get_secret(self):
self.service.get_secret("fake_secret")
self.service._clients.barbican().secrets.get \
.assert_called_once_with("fake_secret")
self._test_atomic_action_timer(self.atomic_actions(),
"barbican.get_secret")
def test__delete_secret(self):
self.service.delete_secret("fake_secret")
self.service._clients.barbican().secrets.delete \
.assert_called_once_with("fake_secret")
self._test_atomic_action_timer(self.atomic_actions(),
"barbican.delete_secret")

View File

@ -87,6 +87,7 @@ pyOpenSSL===18.0.0
pyparsing===2.2.2
pyperclip===1.7.0
Python===2.7.15rc1
python-barbicanclient===4.5.2
python-ceilometerclient===2.9.0
python-cinderclient===4.0.1
python-dateutil===2.7.3