Merge "Add manila share type"
This commit is contained in:
commit
5b1080ddc5
109
contrib/heat_manila/heat_manila/resources/share_type.py
Normal file
109
contrib/heat_manila/heat_manila/resources/share_type.py
Normal file
@ -0,0 +1,109 @@
|
||||
#
|
||||
# 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 heat.common.i18n import _
|
||||
from heat.engine import clients
|
||||
from heat.engine import properties
|
||||
from heat.engine import resource
|
||||
from heat.engine import support
|
||||
|
||||
|
||||
class ManilaShareType(resource.Resource):
|
||||
"""
|
||||
A resource for creating manila share type.
|
||||
|
||||
A share_type is an administrator-defined "type of service", comprised of
|
||||
a tenant visible description, and a list of non-tenant-visible key/value
|
||||
pairs (extra_specs) which the Manila scheduler uses to make scheduling
|
||||
decisions for shared filesystem tasks.
|
||||
|
||||
Please note that share type is intended to use mostly by administrators.
|
||||
So it is very likely that Manila will prohibit creation of the resource
|
||||
without administration grants.
|
||||
"""
|
||||
|
||||
support_status = support.SupportStatus(version='2015.2')
|
||||
|
||||
PROPERTIES = (
|
||||
NAME, IS_PUBLIC, DRIVER_HANDLES_SHARE_SERVERS, EXTRA_SPECS
|
||||
) = (
|
||||
'name', 'is_public', 'driver_handles_share_servers', 'extra_specs'
|
||||
)
|
||||
|
||||
properties_schema = {
|
||||
NAME: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Name of the share type.'),
|
||||
required=True
|
||||
),
|
||||
IS_PUBLIC: properties.Schema(
|
||||
properties.Schema.BOOLEAN,
|
||||
_('Defines if share type is accessible to the public.'),
|
||||
default=True
|
||||
),
|
||||
DRIVER_HANDLES_SHARE_SERVERS: properties.Schema(
|
||||
properties.Schema.BOOLEAN,
|
||||
_('Required extra specification. '
|
||||
'Defines if share drivers handles share servers. '),
|
||||
required=True,
|
||||
),
|
||||
EXTRA_SPECS: properties.Schema(
|
||||
properties.Schema.MAP,
|
||||
_("Extra specs key-value pairs defined for share type."),
|
||||
update_allowed=True
|
||||
)
|
||||
}
|
||||
|
||||
default_client_name = 'manila'
|
||||
|
||||
def handle_create(self):
|
||||
share_type = self.client().share_types.create(
|
||||
name=self.properties.get(self.NAME),
|
||||
spec_driver_handles_share_servers=self.properties.get(
|
||||
self.DRIVER_HANDLES_SHARE_SERVERS),
|
||||
is_public=self.properties.get(self.IS_PUBLIC)
|
||||
)
|
||||
self.resource_id_set(share_type.id)
|
||||
extra_specs = self.properties.get(self.EXTRA_SPECS)
|
||||
if extra_specs:
|
||||
share_type.set_keys(extra_specs)
|
||||
|
||||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||
if self.EXTRA_SPECS in prop_diff:
|
||||
share_type = self.client().share_types.get(self.resource_id)
|
||||
extra_specs_old = self.properties.get(self.EXTRA_SPECS)
|
||||
if extra_specs_old:
|
||||
share_type.unset_keys(extra_specs_old)
|
||||
share_type.set_keys(prop_diff.get(self.EXTRA_SPECS))
|
||||
|
||||
def handle_delete(self):
|
||||
if not self.resource_id:
|
||||
return True
|
||||
|
||||
try:
|
||||
self.client().share_types.delete(self.resource_id)
|
||||
except Exception as ex:
|
||||
self.client_plugin().ignore_not_found(ex)
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
return {
|
||||
'OS::Manila::ShareType': ManilaShareType
|
||||
}
|
||||
|
||||
|
||||
def available_resource_mapping():
|
||||
if not clients.has_client('manila'):
|
||||
return {}
|
||||
|
||||
return resource_mapping()
|
0
contrib/heat_manila/heat_manila/tests/__init__.py
Normal file
0
contrib/heat_manila/heat_manila/tests/__init__.py
Normal file
116
contrib/heat_manila/heat_manila/tests/test_share_type.py
Normal file
116
contrib/heat_manila/heat_manila/tests/test_share_type.py
Normal file
@ -0,0 +1,116 @@
|
||||
#
|
||||
# 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 copy
|
||||
|
||||
import mock
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine import resource
|
||||
from heat.engine import rsrc_defn
|
||||
from heat.engine import scheduler
|
||||
from heat.tests import common
|
||||
from heat.tests import utils
|
||||
|
||||
from ..resources import share_type as mshare_type # noqa
|
||||
|
||||
manila_template = """
|
||||
heat_template_version: 2013-05-23
|
||||
resources:
|
||||
test_share_type:
|
||||
type: OS::Manila::ShareType
|
||||
properties:
|
||||
name: test_share_type
|
||||
driver_handles_share_servers: True
|
||||
extra_specs: {"test":"test"}
|
||||
is_public: False
|
||||
"""
|
||||
|
||||
|
||||
class ManilaShareTypeTest(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ManilaShareTypeTest, self).setUp()
|
||||
utils.setup_dummy_db()
|
||||
self.ctx = utils.dummy_context()
|
||||
resource._register_class("OS::Manila::ShareType",
|
||||
mshare_type.ManilaShareType)
|
||||
|
||||
@staticmethod
|
||||
def _init_share(stack_name, share_type_name="test_share_type"):
|
||||
# parse stack
|
||||
tmp = template_format.parse(manila_template)
|
||||
stack = utils.parse_stack(tmp, stack_name=stack_name)
|
||||
res_def = stack.t.resource_definitions(stack)["test_share_type"]
|
||||
share_type = mshare_type.ManilaShareType(
|
||||
share_type_name, res_def, stack)
|
||||
# mock clients and plugins
|
||||
mock_client = mock.MagicMock()
|
||||
client = mock.MagicMock(return_value=mock_client)
|
||||
share_type.client = client
|
||||
mock_plugin = mock.MagicMock()
|
||||
client_plugin = mock.MagicMock(return_value=mock_plugin)
|
||||
share_type.client_plugin = client_plugin
|
||||
|
||||
return share_type
|
||||
|
||||
def test_share_type_create(self):
|
||||
share_type = self._init_share("stack_share_type_create")
|
||||
fake_share_type = mock.MagicMock(id="type_id")
|
||||
share_type.client().share_types.create.return_value = fake_share_type
|
||||
scheduler.TaskRunner(share_type.create)()
|
||||
self.assertEqual("type_id", share_type.resource_id)
|
||||
share_type.client().share_types.create.assert_called_once_with(
|
||||
name="test_share_type", spec_driver_handles_share_servers=True,
|
||||
is_public=False)
|
||||
fake_share_type.set_keys.assert_called_once_with({"test": "test"})
|
||||
|
||||
def test_share_type_delete(self):
|
||||
share_type = self._init_share("stack_share_type_delete")
|
||||
fake_share_type = mock.MagicMock(id="type_id")
|
||||
share_type.client().share_types.create.return_value = fake_share_type
|
||||
scheduler.TaskRunner(share_type.create)()
|
||||
|
||||
scheduler.TaskRunner(share_type.delete)()
|
||||
share_type.client().share_types.delete.assert_called_once_with(
|
||||
"type_id")
|
||||
|
||||
def test_share_type_delete_not_found(self):
|
||||
share_type = self._init_share("stack_share_type_delete_not_found")
|
||||
fake_share_type = mock.MagicMock(id="type_id")
|
||||
share_type.client().share_types.create.return_value = fake_share_type
|
||||
scheduler.TaskRunner(share_type.create)()
|
||||
|
||||
exc = exception.NotFound()
|
||||
share_type.client().share_types.delete.side_effect = exc
|
||||
scheduler.TaskRunner(share_type.delete)()
|
||||
share_type.client_plugin().ignore_not_found.assert_called_once_with(
|
||||
exc)
|
||||
|
||||
def test_share_type_update(self):
|
||||
share_type = self._init_share("stack_share_type_update")
|
||||
share_type.client().share_types.create.return_value = mock.MagicMock(
|
||||
id="type_id")
|
||||
fake_share_type = mock.MagicMock()
|
||||
share_type.client().share_types.get.return_value = fake_share_type
|
||||
scheduler.TaskRunner(share_type.create)()
|
||||
updated_props = copy.deepcopy(share_type.properties.data)
|
||||
updated_props[mshare_type.ManilaShareType.EXTRA_SPECS] = {
|
||||
"fake_key": "fake_value"}
|
||||
after = rsrc_defn.ResourceDefinition(share_type.name,
|
||||
share_type.type(), updated_props)
|
||||
scheduler.TaskRunner(share_type.update, after)()
|
||||
fake_share_type.unset_keys.assert_called_once_with({"test": "test"})
|
||||
fake_share_type.set_keys.assert_called_with(
|
||||
updated_props[mshare_type.ManilaShareType.EXTRA_SPECS])
|
Loading…
Reference in New Issue
Block a user