[Manila] Add security-services context
Add possibility to create "security-services" on-fly and attach them to "share-networks". Note that, it is not added to benchmarks as it cannot be tested in CI because requires appropriate services be set up and running. Change-Id: I64aa960f3109bfb576da2c2260b017925d4c7c68
This commit is contained in:
parent
8a1672f293
commit
a3da693878
@ -14,3 +14,4 @@
|
||||
# under the License.
|
||||
|
||||
SHARE_NETWORKS_CONTEXT_NAME = "manila_share_networks"
|
||||
SECURITY_SERVICES_CONTEXT_NAME = "manila_security_services"
|
||||
|
@ -0,0 +1,88 @@
|
||||
# Copyright 2015 Mirantis 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from rally.common.i18n import _
|
||||
from rally.common import logging
|
||||
from rally.common import utils
|
||||
from rally import consts as rally_consts
|
||||
from rally.plugins.openstack.cleanup import manager as resource_manager
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack.scenarios.manila import utils as manila_utils
|
||||
from rally.task import context
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONTEXT_NAME = consts.SECURITY_SERVICES_CONTEXT_NAME
|
||||
|
||||
|
||||
@context.configure(name=CONTEXT_NAME, order=445)
|
||||
class SecurityServices(context.Context):
|
||||
"""This context creates 'security services' for Manila project."""
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": rally_consts.JSON_SCHEMA,
|
||||
"properties": {
|
||||
# NOTE(vponomaryov): context arg 'security_services' is expected
|
||||
# to be list of dicts with data for creation of security services.
|
||||
# Example:
|
||||
# security_services = [
|
||||
# {'type': 'LDAP', 'dns_ip': 'foo_ip', 'server': 'bar_ip',
|
||||
# 'domain': 'quuz_domain', 'user': 'ololo',
|
||||
# 'password': 'fake_password'}
|
||||
# ]
|
||||
# Where 'type' is required key and should have one of following
|
||||
# values: 'active_directory', 'kerberos' or 'ldap'.
|
||||
# This context arg is used only if share networks are used and
|
||||
# autocreated.
|
||||
"security_services": {"type": "array"},
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
DEFAULT_CONFIG = {
|
||||
"security_services": [],
|
||||
}
|
||||
|
||||
@logging.log_task_wrapper(
|
||||
LOG.info, _("Enter context: `%s`") % CONTEXT_NAME)
|
||||
def setup(self):
|
||||
for user, tenant_id in (utils.iterate_per_tenants(
|
||||
self.context.get("users", []))):
|
||||
self.context["tenants"][tenant_id][CONTEXT_NAME] = {
|
||||
"security_services": [],
|
||||
}
|
||||
if self.config["security_services"]:
|
||||
manila_scenario = manila_utils.ManilaScenario({
|
||||
"task": self.task,
|
||||
"user": user,
|
||||
"config": {
|
||||
"api_versions": self.context["config"].get(
|
||||
"api_versions", [])}
|
||||
})
|
||||
for ss in self.config["security_services"]:
|
||||
inst = manila_scenario._create_security_service(
|
||||
**ss).to_dict()
|
||||
self.context["tenants"][tenant_id][CONTEXT_NAME][
|
||||
"security_services"].append(inst)
|
||||
|
||||
@logging.log_task_wrapper(LOG.info, _("Exit context: `%s`") % CONTEXT_NAME)
|
||||
def cleanup(self):
|
||||
resource_manager.cleanup(
|
||||
names=["manila.security_services"],
|
||||
users=self.context.get("users", []),
|
||||
)
|
@ -153,6 +153,11 @@ class ShareNetworks(context.Context):
|
||||
**data).to_dict()
|
||||
self.context["tenants"][tenant_id][CONTEXT_NAME][
|
||||
"share_networks"].append(share_network)
|
||||
for ss in self.context["tenants"][tenant_id].get(
|
||||
consts.SECURITY_SERVICES_CONTEXT_NAME, {}).get(
|
||||
"security_services", []):
|
||||
manila_scenario._add_security_service_to_share_network(
|
||||
share_network["id"], ss["id"])
|
||||
|
||||
if networks:
|
||||
for network in networks:
|
||||
|
@ -1,3 +1,4 @@
|
||||
{% set use_security_services = use_security_services or False %}
|
||||
{
|
||||
"ManilaShares.create_and_delete_share": [
|
||||
{
|
||||
@ -32,6 +33,28 @@
|
||||
"manila_share_networks": {
|
||||
"use_share_networks": true
|
||||
}
|
||||
{% if use_security_services %}
|
||||
,
|
||||
"manila_security_services": {
|
||||
"security_services": [
|
||||
{"security_service_type": "ldap",
|
||||
"server": "LDAP server address",
|
||||
"user": "User that will be used",
|
||||
"password": "Password for specified user"},
|
||||
{"security_service_type": "kerberos",
|
||||
"dns_ip": "IP address of DNS service to be used",
|
||||
"server": "Kerberos server address",
|
||||
"domain": "Kerberos realm",
|
||||
"user": "User that will be used",
|
||||
"password": "Password for specified user"},
|
||||
{"security_service_type": "active_directory",
|
||||
"dns_ip": "IP address of DNS service to be used",
|
||||
"domain": "Domain from 'Active Directory'",
|
||||
"user": "User from 'Active Directory'",
|
||||
"password": "password for specified user"}
|
||||
]
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,3 +1,4 @@
|
||||
{% set use_security_services = use_security_services or False %}
|
||||
---
|
||||
ManilaShares.create_and_delete_share:
|
||||
-
|
||||
@ -25,3 +26,23 @@
|
||||
start_cidr: "99.0.0.0/24"
|
||||
manila_share_networks:
|
||||
use_share_networks: True
|
||||
{% if use_security_services %}
|
||||
manila_security_services:
|
||||
security_services: [
|
||||
{"security_service_type": "ldap",
|
||||
"server": "LDAP server address",
|
||||
"user": "User that will be used",
|
||||
"password": "Password for specified user"},
|
||||
{"security_service_type": "kerberos",
|
||||
"dns_ip": "IP address of DNS service to be used",
|
||||
"server": "Kerberos server address",
|
||||
"domain": "Kerberos realm",
|
||||
"user": "User that will be used",
|
||||
"password": "Password for specified user"},
|
||||
{"security_service_type": "active_directory",
|
||||
"dns_ip": "IP address of DNS service to be used",
|
||||
"domain": "Domain from 'Active Directory'",
|
||||
"user": "User from 'Active Directory'",
|
||||
"password": "password for specified user"},
|
||||
]
|
||||
{% endif %}
|
||||
|
@ -0,0 +1,172 @@
|
||||
# Copyright 2015 Mirantis 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 ddt
|
||||
import mock
|
||||
import six
|
||||
|
||||
from rally import consts as rally_consts
|
||||
from rally.plugins.openstack.context.manila import consts
|
||||
from rally.plugins.openstack.context.manila import manila_security_services
|
||||
from tests.unit import test
|
||||
|
||||
CONTEXT_NAME = consts.SECURITY_SERVICES_CONTEXT_NAME
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class SecurityServicesTestCase(test.ScenarioTestCase):
|
||||
TENANTS_AMOUNT = 3
|
||||
USERS_PER_TENANT = 4
|
||||
SECURITY_SERVICES = [
|
||||
{"security_service_type": ss_type,
|
||||
"dns_ip": "fake_dns_ip_%s" % ss_type,
|
||||
"server": "fake_server_%s" % ss_type,
|
||||
"domain": "fake_domain_%s" % ss_type,
|
||||
"user": "fake_user_%s" % ss_type,
|
||||
"password": "fake_password_%s" % ss_type}
|
||||
for ss_type in ("ldap", "kerberos", "active_directory")
|
||||
]
|
||||
|
||||
def _get_context(self, security_services=None, networks_per_tenant=2,
|
||||
neutron_network_provider=True):
|
||||
if security_services is None:
|
||||
security_services = self.SECURITY_SERVICES
|
||||
tenants = {}
|
||||
for t_id in range(self.TENANTS_AMOUNT):
|
||||
tenants[six.text_type(t_id)] = {"name": six.text_type(t_id)}
|
||||
tenants[six.text_type(t_id)]["networks"] = []
|
||||
for i in range(networks_per_tenant):
|
||||
network = {"id": "fake_net_id_%s" % i}
|
||||
if neutron_network_provider:
|
||||
network["subnets"] = ["fake_subnet_id_of_net_%s" % i]
|
||||
else:
|
||||
network["cidr"] = "101.0.5.0/24"
|
||||
tenants[six.text_type(t_id)]["networks"].append(network)
|
||||
users = []
|
||||
for t_id in tenants.keys():
|
||||
for i in range(self.USERS_PER_TENANT):
|
||||
users.append({"id": i, "tenant_id": t_id, "endpoint": "fake"})
|
||||
context = {
|
||||
"config": {
|
||||
"users": {
|
||||
"tenants": self.TENANTS_AMOUNT,
|
||||
"users_per_tenant": self.USERS_PER_TENANT,
|
||||
},
|
||||
CONTEXT_NAME: {
|
||||
"security_services": security_services,
|
||||
},
|
||||
},
|
||||
"admin": {
|
||||
"endpoint": mock.MagicMock(),
|
||||
},
|
||||
"task": mock.MagicMock(),
|
||||
"users": users,
|
||||
"tenants": tenants,
|
||||
}
|
||||
return context
|
||||
|
||||
def test_init(self):
|
||||
context = {
|
||||
"task": mock.MagicMock(),
|
||||
"config": {
|
||||
CONTEXT_NAME: {"foo": "bar"},
|
||||
"not_manila": {"not_manila_key": "not_manila_value"},
|
||||
}
|
||||
}
|
||||
|
||||
inst = manila_security_services.SecurityServices(context)
|
||||
|
||||
self.assertEqual(inst.config.get("foo"), "bar")
|
||||
self.assertFalse(inst.config.get("security_services"))
|
||||
self.assertIn(
|
||||
rally_consts.JSON_SCHEMA, inst.CONFIG_SCHEMA.get("$schema"))
|
||||
self.assertEqual(False, inst.CONFIG_SCHEMA.get("additionalProperties"))
|
||||
self.assertEqual("object", inst.CONFIG_SCHEMA.get("type"))
|
||||
props = inst.CONFIG_SCHEMA.get("properties", {})
|
||||
self.assertEqual({"type": "array"}, props.get("security_services"))
|
||||
self.assertEqual(445, inst.get_order())
|
||||
self.assertEqual(CONTEXT_NAME, inst.get_name())
|
||||
|
||||
@mock.patch.object(manila_security_services.manila_utils, "ManilaScenario")
|
||||
@ddt.data(True, False)
|
||||
def test_setup_security_services_set(self, neutron_network_provider,
|
||||
mock_manila_scenario):
|
||||
ctxt = self._get_context(
|
||||
neutron_network_provider=neutron_network_provider)
|
||||
inst = manila_security_services.SecurityServices(ctxt)
|
||||
|
||||
inst.setup()
|
||||
|
||||
self.assertEqual(
|
||||
self.TENANTS_AMOUNT, mock_manila_scenario.call_count)
|
||||
self.assertEqual(
|
||||
mock_manila_scenario.call_args_list,
|
||||
[mock.call({
|
||||
"task": inst.task,
|
||||
"config": {"api_versions": []},
|
||||
"user": user})
|
||||
for user in inst.context["users"] if user["id"] == 0]
|
||||
)
|
||||
mock_create_security_service = (
|
||||
mock_manila_scenario.return_value._create_security_service)
|
||||
expected_calls = []
|
||||
for ss in self.SECURITY_SERVICES:
|
||||
expected_calls.extend([mock.call(**ss), mock.call().to_dict()])
|
||||
mock_create_security_service.assert_has_calls(expected_calls)
|
||||
self.assertEqual(
|
||||
self.TENANTS_AMOUNT * len(self.SECURITY_SERVICES),
|
||||
mock_create_security_service.call_count)
|
||||
self.assertEqual(
|
||||
self.TENANTS_AMOUNT,
|
||||
len(inst.context["config"][CONTEXT_NAME]["security_services"]))
|
||||
for tenant in inst.context["tenants"]:
|
||||
self.assertEqual(
|
||||
self.TENANTS_AMOUNT,
|
||||
len(inst.context["tenants"][tenant][CONTEXT_NAME][
|
||||
"security_services"])
|
||||
)
|
||||
|
||||
@mock.patch.object(manila_security_services.manila_utils, "ManilaScenario")
|
||||
def test_setup_security_services_not_set(self, mock_manila_scenario):
|
||||
ctxt = self._get_context(security_services=[])
|
||||
inst = manila_security_services.SecurityServices(ctxt)
|
||||
|
||||
inst.setup()
|
||||
|
||||
self.assertFalse(mock_manila_scenario.called)
|
||||
self.assertFalse(
|
||||
mock_manila_scenario.return_value._create_security_service.called)
|
||||
self.assertIn(CONTEXT_NAME, inst.context["config"])
|
||||
self.assertIn(
|
||||
"security_services", inst.context["config"][CONTEXT_NAME])
|
||||
self.assertEqual(
|
||||
0,
|
||||
len(inst.context["config"][CONTEXT_NAME]["security_services"]))
|
||||
for tenant in inst.context["tenants"]:
|
||||
self.assertEqual(
|
||||
0,
|
||||
len(inst.context["tenants"][tenant][CONTEXT_NAME][
|
||||
"security_services"])
|
||||
)
|
||||
|
||||
@mock.patch.object(manila_security_services, "resource_manager")
|
||||
def test_cleanup_security_services_enabled(self, mock_resource_manager):
|
||||
ctxt = self._get_context()
|
||||
inst = manila_security_services.SecurityServices(ctxt)
|
||||
|
||||
inst.cleanup()
|
||||
|
||||
mock_resource_manager.cleanup.assert_called_once_with(
|
||||
names=["manila.security_services"], users=ctxt["users"])
|
@ -56,7 +56,7 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
for ss_type in ("ldap", "kerberos", "active_directory")
|
||||
]
|
||||
|
||||
def _get_context(self, networks_per_tenant=2,
|
||||
def _get_context(self, use_security_services=False, networks_per_tenant=2,
|
||||
neutron_network_provider=True):
|
||||
tenants = {}
|
||||
for t_id in range(self.TENANTS_AMOUNT):
|
||||
@ -85,6 +85,11 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
"use_share_networks": True,
|
||||
"share_networks": [],
|
||||
},
|
||||
consts.SECURITY_SERVICES_CONTEXT_NAME: {
|
||||
"security_services": (
|
||||
self.SECURITY_SERVICES
|
||||
if use_security_services else [])
|
||||
},
|
||||
"network": {
|
||||
"networks_per_tenant": networks_per_tenant,
|
||||
"start_cidr": "101.0.5.0/24",
|
||||
@ -242,6 +247,64 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
|
||||
self.assertRaises(exceptions.ContextSetupFailure, inst.setup)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_create_share_network")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_add_security_service_to_share_network")
|
||||
def test_setup_autocreate_share_networks_with_security_services(
|
||||
self,
|
||||
neutron,
|
||||
mock_manila_scenario__add_security_service_to_share_network,
|
||||
mock_manila_scenario__create_share_network,
|
||||
mock_clients):
|
||||
networks_per_tenant = 2
|
||||
ctxt = self._get_context(
|
||||
networks_per_tenant=networks_per_tenant,
|
||||
neutron_network_provider=neutron,
|
||||
use_security_services=True,
|
||||
)
|
||||
inst = manila_share_networks.ShareNetworks(ctxt)
|
||||
for tenant_id in list(ctxt["tenants"].keys()):
|
||||
inst.context["tenants"][tenant_id][
|
||||
consts.SECURITY_SERVICES_CONTEXT_NAME] = {
|
||||
"security_services": [
|
||||
Fake(id="fake_id").to_dict() for i in (1, 2, 3)
|
||||
]
|
||||
}
|
||||
|
||||
inst.setup()
|
||||
|
||||
self.assertEqual(ctxt["task"], inst.context.get("task"))
|
||||
self.assertEqual(ctxt["config"], inst.context.get("config"))
|
||||
self.assertEqual(ctxt["users"], inst.context.get("users"))
|
||||
self.assertEqual(ctxt["tenants"], inst.context.get("tenants"))
|
||||
mock_add_security_service_to_share_network = (
|
||||
mock_manila_scenario__add_security_service_to_share_network)
|
||||
mock_add_security_service_to_share_network.assert_has_calls([
|
||||
mock.call(mock.ANY, mock.ANY)
|
||||
for i in range(
|
||||
self.TENANTS_AMOUNT *
|
||||
networks_per_tenant *
|
||||
len(self.SECURITY_SERVICES))])
|
||||
if neutron:
|
||||
sn_args = {
|
||||
"neutron_net_id": mock.ANY,
|
||||
"neutron_subnet_id": mock.ANY,
|
||||
}
|
||||
else:
|
||||
sn_args = {"nova_net_id": mock.ANY}
|
||||
expected_calls = [
|
||||
mock.call(**sn_args),
|
||||
mock.call().to_dict(),
|
||||
mock.ANY,
|
||||
mock.ANY,
|
||||
mock.ANY,
|
||||
]
|
||||
mock_manila_scenario__create_share_network.assert_has_calls(
|
||||
expected_calls * (self.TENANTS_AMOUNT * networks_per_tenant))
|
||||
mock_clients.assert_has_calls([
|
||||
mock.call("fake", {}) for i in range(self.TENANTS_AMOUNT)])
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_create_share_network")
|
||||
@ -329,6 +392,7 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
self.assertIn(mock.call(user["credential"], {}),
|
||||
mock_clients.mock_calls)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch("rally.task.utils.wait_for_status")
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_delete_share_network")
|
||||
@ -336,7 +400,7 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
@mock.patch(MANILA_UTILS_PATH + "_add_security_service_to_share_network")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_list_share_servers")
|
||||
def test_cleanup_autocreated_share_networks(
|
||||
self,
|
||||
self, use_security_services,
|
||||
mock_manila_scenario__list_share_servers,
|
||||
mock_manila_scenario__add_security_service_to_share_network,
|
||||
mock_manila_scenario__create_share_network,
|
||||
@ -349,8 +413,16 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
networks_per_tenant = 2
|
||||
ctxt = self._get_context(
|
||||
networks_per_tenant=networks_per_tenant,
|
||||
use_security_services=use_security_services,
|
||||
)
|
||||
inst = manila_share_networks.ShareNetworks(ctxt)
|
||||
for tenant_id in list(ctxt["tenants"].keys()):
|
||||
inst.context["tenants"][tenant_id][
|
||||
consts.SECURITY_SERVICES_CONTEXT_NAME] = {
|
||||
"security_services": [
|
||||
Fake(id="fake_id").to_dict() for i in (1, 2, 3)
|
||||
]
|
||||
}
|
||||
inst.setup()
|
||||
|
||||
mock_clients.assert_has_calls([
|
||||
|
Loading…
Reference in New Issue
Block a user