Add cinder actions

* Mistral now includes all Cinder actions
 * Unit tests

Change-Id: Ia663df09ae15f8154d49bbf232118617f92cba30
This commit is contained in:
Nikolay Mahotkin 2014-11-05 15:19:29 +03:00
parent 9ba091ae6e
commit 0ee563d7e4
8 changed files with 219 additions and 4 deletions

View File

@ -21,5 +21,6 @@ def all_generators():
generators.GlanceActionGenerator, generators.GlanceActionGenerator,
generators.KeystoneActionGenerator, generators.KeystoneActionGenerator,
generators.HeatActionGenerator, generators.HeatActionGenerator,
generators.NeutronActionGenerator generators.NeutronActionGenerator,
generators.CinderActionGenerator
] ]

View File

@ -39,3 +39,8 @@ class HeatActionGenerator(base.OpenStackActionGenerator):
class NeutronActionGenerator(base.OpenStackActionGenerator): class NeutronActionGenerator(base.OpenStackActionGenerator):
action_namespace = "neutron" action_namespace = "neutron"
base_action_class = actions.NeutronAction base_action_class = actions.NeutronAction
class CinderActionGenerator(base.OpenStackActionGenerator):
action_namespace = "cinder"
base_action_class = actions.CinderAction

View File

@ -14,6 +14,7 @@
import inspect import inspect
from cinderclient.v1 import client as cinderclient
from glanceclient.v2 import client as glanceclient from glanceclient.v2 import client as glanceclient
from heatclient.v1 import client as heatclient from heatclient.v1 import client as heatclient
from keystoneclient import httpclient from keystoneclient import httpclient
@ -145,4 +146,32 @@ class NeutronAction(base.OpenStackAction):
endpoint_url=keystone_utils.get_endpoint_for_project('neutron'), endpoint_url=keystone_utils.get_endpoint_for_project('neutron'),
token=ctx.auth_token, token=ctx.auth_token,
auth_url=CONF.keystone_authtoken.auth_uri auth_url=CONF.keystone_authtoken.auth_uri
) )
class CinderAction(base.OpenStackAction):
_client_class = cinderclient.Client
def _get_client(self):
ctx = context.ctx()
LOG.debug("Cinder action security context: %s" % ctx)
cinder_url = keystone_utils.get_endpoint_for_project(
service_type='volume'
)
cinder_url = cinder_url % {'tenant_id': ctx.project_id}
client = self._client_class(
ctx.user_name,
ctx.auth_token,
project_id=ctx.project_id,
auth_url=cinder_url,
)
client.client.auth_token = ctx.auth_token
client.client.management_url = cinder_url
return client
@classmethod
def _get_fake_client(cls):
return cls._client_class()

View File

@ -516,5 +516,136 @@
"update_subnet": "update_subnet", "update_subnet": "update_subnet",
"update_vip": "update_vip", "update_vip": "update_vip",
"update_vpnservice": "update_vpnservice" "update_vpnservice": "update_vpnservice"
},
"cinder": {
"_comment": "It uses cinderclient.v1.",
"availability_zones_completion_cache": "availability_zones.completion_cache",
"availability_zones_find": "availability_zones.find",
"availability_zones_findall": "availability_zones.findall",
"availability_zones_list": "availability_zones.list",
"availability_zones_write_to_completion_cache": "availability_zones.write_to_completion_cache",
"backups_completion_cache": "backups.completion_cache",
"backups_create": "backups.create",
"backups_delete": "backups.delete",
"backups_export_record": "backups.export_record",
"backups_find": "backups.find",
"backups_findall": "backups.findall",
"backups_get": "backups.get",
"backups_import_record": "backups.import_record",
"backups_list": "backups.list",
"backups_write_to_completion_cache": "backups.write_to_completion_cache",
"get_volume_api_version_from_endpoint": "get_volume_api_version_from_endpoint",
"limits_completion_cache": "limits.completion_cache",
"limits_get": "limits.get",
"limits_write_to_completion_cache": "limits.write_to_completion_cache",
"qos_specs_associate": "qos_specs.associate",
"qos_specs_completion_cache": "qos_specs.completion_cache",
"qos_specs_create": "qos_specs.create",
"qos_specs_delete": "qos_specs.delete",
"qos_specs_disassociate": "qos_specs.disassociate",
"qos_specs_disassociate_all": "qos_specs.disassociate_all",
"qos_specs_find": "qos_specs.find",
"qos_specs_findall": "qos_specs.findall",
"qos_specs_get": "qos_specs.get",
"qos_specs_get_associations": "qos_specs.get_associations",
"qos_specs_list": "qos_specs.list",
"qos_specs_set_keys": "qos_specs.set_keys",
"qos_specs_unset_keys": "qos_specs.unset_keys",
"qos_specs_write_to_completion_cache": "qos_specs.write_to_completion_cache",
"quota_classes_completion_cache": "quota_classes.completion_cache",
"quota_classes_get": "quota_classes.get",
"quota_classes_update": "quota_classes.update",
"quota_classes_write_to_completion_cache": "quota_classes.write_to_completion_cache",
"quotas_completion_cache": "quotas.completion_cache",
"quotas_defaults": "quotas.defaults",
"quotas_delete": "quotas.delete",
"quotas_get": "quotas.get",
"quotas_update": "quotas.update",
"quotas_write_to_completion_cache": "quotas.write_to_completion_cache",
"restores_completion_cache": "restores.completion_cache",
"restores_restore": "restores.restore",
"restores_write_to_completion_cache": "restores.write_to_completion_cache",
"services_completion_cache": "services.completion_cache",
"services_disable": "services.disable",
"services_disable_log_reason": "services.disable_log_reason",
"services_enable": "services.enable",
"services_find": "services.find",
"services_findall": "services.findall",
"services_list": "services.list",
"services_write_to_completion_cache": "services.write_to_completion_cache",
"transfers_accept": "transfers.accept",
"transfers_completion_cache": "transfers.completion_cache",
"transfers_create": "transfers.create",
"transfers_delete": "transfers.delete",
"transfers_find": "transfers.find",
"transfers_findall": "transfers.findall",
"transfers_get": "transfers.get",
"transfers_list": "transfers.list",
"transfers_write_to_completion_cache": "transfers.write_to_completion_cache",
"volume_encryption_types_completion_cache": "volume_encryption_types.completion_cache",
"volume_encryption_types_create": "volume_encryption_types.create",
"volume_encryption_types_delete": "volume_encryption_types.delete",
"volume_encryption_types_find": "volume_encryption_types.find",
"volume_encryption_types_findall": "volume_encryption_types.findall",
"volume_encryption_types_get": "volume_encryption_types.get",
"volume_encryption_types_list": "volume_encryption_types.list",
"volume_encryption_types_update": "volume_encryption_types.update",
"volume_encryption_types_write_to_completion_cache": "volume_encryption_types.write_to_completion_cache",
"volume_snapshots_completion_cache": "volume_snapshots.completion_cache",
"volume_snapshots_create": "volume_snapshots.create",
"volume_snapshots_delete": "volume_snapshots.delete",
"volume_snapshots_delete_metadata": "volume_snapshots.delete_metadata",
"volume_snapshots_find": "volume_snapshots.find",
"volume_snapshots_findall": "volume_snapshots.findall",
"volume_snapshots_get": "volume_snapshots.get",
"volume_snapshots_list": "volume_snapshots.list",
"volume_snapshots_reset_state": "volume_snapshots.reset_state",
"volume_snapshots_set_metadata": "volume_snapshots.set_metadata",
"volume_snapshots_update": "volume_snapshots.update",
"volume_snapshots_update_all_metadata": "volume_snapshots.update_all_metadata",
"volume_snapshots_update_snapshot_status": "volume_snapshots.update_snapshot_status",
"volume_snapshots_write_to_completion_cache": "volume_snapshots.write_to_completion_cache",
"volume_types_completion_cache": "volume_types.completion_cache",
"volume_types_create": "volume_types.create",
"volume_types_delete": "volume_types.delete",
"volume_types_find": "volume_types.find",
"volume_types_findall": "volume_types.findall",
"volume_types_get": "volume_types.get",
"volume_types_list": "volume_types.list",
"volume_types_write_to_completion_cache": "volume_types.write_to_completion_cache",
"volumes_attach": "volumes.attach",
"volumes_begin_detaching": "volumes.begin_detaching",
"volumes_completion_cache": "volumes.completion_cache",
"volumes_create": "volumes.create",
"volumes_delete": "volumes.delete",
"volumes_delete_metadata": "volumes.delete_metadata",
"volumes_detach": "volumes.detach",
"volumes_extend": "volumes.extend",
"volumes_find": "volumes.find",
"volumes_findall": "volumes.findall",
"volumes_force_delete": "volumes.force_delete",
"volumes_get": "volumes.get",
"volumes_get_encryption_metadata": "volumes.get_encryption_metadata",
"volumes_initialize_connection": "volumes.initialize_connection",
"volumes_list": "volumes.list",
"volumes_manage": "volumes.manage",
"volumes_migrate_volume": "volumes.migrate_volume",
"volumes_migrate_volume_completion": "volumes.migrate_volume_completion",
"volumes_promote": "volumes.promote",
"volumes_reenable": "volumes.reenable",
"volumes_reserve": "volumes.reserve",
"volumes_reset_state": "volumes.reset_state",
"volumes_retype": "volumes.retype",
"volumes_roll_detaching": "volumes.roll_detaching",
"volumes_set_bootable": "volumes.set_bootable",
"volumes_set_metadata": "volumes.set_metadata",
"volumes_terminate_connection": "volumes.terminate_connection",
"volumes_unmanage": "volumes.unmanage",
"volumes_unreserve": "volumes.unreserve",
"volumes_update": "volumes.update",
"volumes_update_all_metadata": "volumes.update_all_metadata",
"volumes_update_readonly_flag": "volumes.update_readonly_flag",
"volumes_upload_to_image": "volumes.upload_to_image",
"volumes_write_to_completion_cache": "volumes.write_to_completion_cache"
} }
} }

View File

@ -0,0 +1,32 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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 mistral.actions.openstack.action_generator import generators
from mistral.actions.openstack import actions
from mistral.tests import base
class CinderGeneratorTest(base.BaseTest):
def test_generator(self):
action_name = "cinder.volumes_list"
generator = generators.CinderActionGenerator
action_classes = generator.create_actions()
action = self._assert_single_item(
action_classes,
name=action_name
)
self.assertIsNotNone(generator)
self.assertTrue(issubclass(action['class'], actions.CinderAction))
self.assertEqual("volumes.list", action['class'].client_method_name)

View File

@ -78,3 +78,15 @@ class OpenStackActionTest(base.BaseTestCase):
self.assertTrue(mocked().show_network.called) self.assertTrue(mocked().show_network.called)
mocked().show_network.assert_called_once_with(id="1234-abcd") mocked().show_network.assert_called_once_with(id="1234-abcd")
@mock.patch.object(actions.CinderAction, '_get_client')
def test_cinder_action(self, mocked):
method_name = "volumes.get"
action_class = actions.CinderAction
action_class.client_method_name = method_name
params = {'volume': '1234-abcd'}
action = action_class(**params)
action.run()
self.assertTrue(mocked().volumes.get.called)
mocked().volumes.get.assert_called_once_with(volume="1234-abcd")

View File

@ -55,11 +55,15 @@ def client_for_trusts(trust_id):
return _admin_client(trust_id=trust_id) return _admin_client(trust_id=trust_id)
def get_endpoint_for_project(service_name): def get_endpoint_for_project(service_name=None, service_type=None):
admin_project_name = CONF.keystone_authtoken.admin_tenant_name admin_project_name = CONF.keystone_authtoken.admin_tenant_name
keystone_client = _admin_client(project_name=admin_project_name) keystone_client = _admin_client(project_name=admin_project_name)
service_list = keystone_client.services.list() service_list = keystone_client.services.list()
service_id = [s.id for s in service_list if s.name == service_name][0]
if service_name:
service_id = [s.id for s in service_list if s.name == service_name][0]
elif service_type:
service_id = [s.id for s in service_list if s.type == service_type][0]
return keystone_client.endpoints.find(service_id=service_id, return keystone_client.endpoints.find(service_id=service_id,
interface='public').url interface='public').url

View File

@ -15,6 +15,7 @@ oslo.config>=1.4.0 # Apache-2.0
oslo.db>=1.0.0 # Apache-2.0 oslo.db>=1.0.0 # Apache-2.0
oslo.messaging>=1.4.0 oslo.messaging>=1.4.0
paramiko>=1.13.0 paramiko>=1.13.0
python-cinderclient>=1.1.0
python-heatclient>=0.2.9 python-heatclient>=0.2.9
python-keystoneclient>=0.10.0 python-keystoneclient>=0.10.0
python-neutronclient>=2.3.6,<3 python-neutronclient>=2.3.6,<3