Add Trove to mistral actions

Implement Trove actions in mistral, useful for Trove automated backups

Change-Id: I638a7cad1d12d5e08a8a1741e72a75fd19d62233
Implements: blueprint trove-api-actions
This commit is contained in:
Bhaskar Duvvuri 2015-11-19 23:23:14 +05:30
parent c11ef5c435
commit 56e62a5bee
8 changed files with 167 additions and 4 deletions

View File

@ -23,5 +23,6 @@ def all_generators():
generators.HeatActionGenerator, generators.HeatActionGenerator,
generators.NeutronActionGenerator, generators.NeutronActionGenerator,
generators.CinderActionGenerator, generators.CinderActionGenerator,
generators.CeilometerActionGenerator generators.CeilometerActionGenerator,
generators.TroveActionGenerator
] ]

View File

@ -49,3 +49,8 @@ class CinderActionGenerator(base.OpenStackActionGenerator):
class CeilometerActionGenerator(base.OpenStackActionGenerator): class CeilometerActionGenerator(base.OpenStackActionGenerator):
action_namespace = "ceilometer" action_namespace = "ceilometer"
base_action_class = actions.CeilometerAction base_action_class = actions.CeilometerAction
class TroveActionGenerator(base.OpenStackActionGenerator):
action_namespace = "trove"
base_action_class = actions.TroveAction

View File

@ -20,6 +20,8 @@ from keystoneclient import httpclient
from keystoneclient.v3 import client as keystoneclient from keystoneclient.v3 import client as keystoneclient
from neutronclient.v2_0 import client as neutronclient from neutronclient.v2_0 import client as neutronclient
from novaclient import client as novaclient from novaclient import client as novaclient
from troveclient import client as troveclient
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
@ -231,3 +233,38 @@ class CinderAction(base.OpenStackAction):
@classmethod @classmethod
def _get_fake_client(cls): def _get_fake_client(cls):
return cls._client_class() return cls._client_class()
class TroveAction(base.OpenStackAction):
_client_class = troveclient.Client
def _get_client(self):
ctx = context.ctx()
LOG.debug("Trove action security context: %s" % ctx)
trove_endpoint = keystone_utils.get_endpoint_for_project(
service_type='database'
)
trove_url = keystone_utils.format_url(
trove_endpoint.url,
{'tenant_id': ctx.project_id}
)
client = self._client_class(
ctx.user_name,
ctx.auth_token,
project_id=ctx.project_id,
auth_url=trove_url,
region_name=trove_endpoint.region
)
client.client.auth_token = ctx.auth_token
client.client.management_url = trove_url
return client
@classmethod
def _get_fake_client(cls):
return cls._client_class()

View File

@ -795,5 +795,75 @@
"volumes_update_all_metadata": "volumes.update_all_metadata", "volumes_update_all_metadata": "volumes.update_all_metadata",
"volumes_update_readonly_flag": "volumes.update_readonly_flag", "volumes_update_readonly_flag": "volumes.update_readonly_flag",
"volumes_upload_to_image": "volumes.upload_to_image" "volumes_upload_to_image": "volumes.upload_to_image"
},
"trove": {
"_comment": "It uses troveclient.v1.",
"flavors_list": "flavors.list",
"flavors_list_datastore_version_associated_flavors": "flavors.list_datastore_version_associated_flavors",
"flavors_get": "flavors.get",
"users_create": "users.create",
"users_delete": "users.delete",
"users_list": "users.list",
"users_get": "users.get",
"users_update_attributes": "users.update_attributes",
"users_list_access": "users.list_access",
"users_grant": "users.grant",
"users_revoke": "users.revoke",
"users_change_passwords": "users.change_passwords",
"databases_create": "databases.create",
"databases_delete": "databases.delete",
"databases_list": "databases.list",
"backups_list": "backups.list",
"backups_create": "backups.create",
"backups_get": "backups.get",
"backups_delete": "backups.delete",
"clusters_create": "clusters.create",
"clusters_get": "clusters.get",
"clusters_list": "clusters.list",
"clusters_delete": "clusters.delete",
"clusters_add_shard": "clusters.add_shard",
"clusters_grow": "clusters.grow",
"clusters_shrink": "clusters.shrink",
"instances_create": "instances.create",
"instances_modify": "instances.modify",
"instances_edit": "instances.edit",
"instances_list": "instances.list",
"instances_get": "instances.get",
"instances_backups": "instances.backups",
"instances_delete": "instances.delete",
"instances_resize_volume": "instances.resize_volume",
"instances_resize_instance": "instances.resize_instance",
"instances_restart": "instances.restart",
"instances_configuration": "instances.configuration",
"instances_promote_to_replica_source": "instances.promote_to_replica_source",
"instances_eject_replica_source": "instances.eject_replica_source",
"limits_list": "limits.list",
"root_create": "root.create",
"root_create_instance_root": "root.create_instance_root",
"root_create_cluster_root": "root.create_cluster_root",
"root_is_root_enabled": "root.is_root_enabled",
"root_is_instance_root_enabled": "root.is_instance_root_enabled",
"root_is_cluster_root_enabled": "root.is_cluster_root_enabled",
"security_group_rules_create": "security_group_rules.create",
"security_group_rules_delete": "security_group_rules.delete",
"security_groups_list": "security_groups.list",
"security_groups_get": "security_groups.get",
"datastores_list": "datastores.list",
"datastores_get": "datastores.get",
"datastore_versions_list": "datastore_versions.list",
"datastore_versions_get": "datastore_versions.get",
"datastore_versions_get_by_uuid": "datastore_versions.get_by_uuid",
"datastore_versions_update": "datastore_versions.update",
"configurations_get": "configurations.get",
"configurations_instances": "configurations.instances",
"configurations_list": "configurations.list",
"configurations_create": "configurations.create",
"configurations_update": "configurations.update",
"configurations_edit": "configurations.edit",
"configurations_delete": "configurations.delete",
"configuration_parameters_parameters": "configuration_parameters.parameters",
"configuration_parameters_get_parameter": "configuration_parameters.get_parameter",
"configuration_parameters_parameters_by_version": "configuration_parameters.parameters_by_version",
"configuration_parameters_get_parameter_by_version": "configuration_parameters.get_parameter_by_version"
} }
} }

View File

@ -102,3 +102,15 @@ class OpenStackActionTest(base.BaseTestCase):
self.assertTrue(mocked().alarms.get.called) self.assertTrue(mocked().alarms.get.called)
mocked().alarms.get.assert_called_once_with(alarm_id="1234-abcd") mocked().alarms.get.assert_called_once_with(alarm_id="1234-abcd")
@mock.patch.object(actions.TroveAction, '_get_client')
def test_trove_action(self, mocked):
method_name = "instances.get"
action_class = actions.TroveAction
action_class.client_method_name = method_name
params = {'instance': '1234-abcd'}
action = action_class(**params)
action.run()
self.assertTrue(mocked().instances.get.called)
mocked().instances.get.assert_called_once_with(instance="1234-abcd")

View File

@ -0,0 +1,32 @@
# Copyright 2015 - AT&T Services, 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.unit import base
class TroveGeneratorTest(base.BaseTest):
def test_generator(self):
action_name = "trove.instances_list"
generator = generators.TroveActionGenerator
action_classes = generator.create_actions()
action = self._assert_single_item(
action_classes,
name=action_name
)
self.assertIsNotNone(generator)
self.assertTrue(issubclass(action['class'], actions.TroveAction))
self.assertEqual("instances.list", action['class'].client_method_name)

View File

@ -28,6 +28,7 @@ python-heatclient>=0.6.0
python-keystoneclient!=1.8.0,>=1.6.0 python-keystoneclient!=1.8.0,>=1.6.0
python-neutronclient>=2.6.0 python-neutronclient>=2.6.0
python-novaclient!=2.33.0,>=2.29.0 python-novaclient!=2.33.0,>=2.29.0
python-troveclient>=1.2.0
PyYAML>=3.1.0 PyYAML>=3.1.0
requests!=2.8.0,>=2.5.2 requests!=2.8.0,>=2.5.2
retrying!=1.3.0,>=1.2.3 # Apache-2.0 retrying!=1.3.0,>=1.2.3 # Apache-2.0

View File

@ -28,7 +28,8 @@ from keystoneclient import base as keystone_base
from keystoneclient.v3 import client as keystoneclient from keystoneclient.v3 import client as keystoneclient
from novaclient import client as novaclient from novaclient import client as novaclient
from novaclient.openstack.common.apiclient import base as nova_base from novaclient.openstack.common.apiclient import base as nova_base
from troveclient import base as trove_base
from troveclient.v1 import client as troveclient
# TODO(nmakhotkin): Find a rational way to do it for neutron. # TODO(nmakhotkin): Find a rational way to do it for neutron.
# TODO(nmakhotkin): Implement recursive way of searching for managers # TODO(nmakhotkin): Implement recursive way of searching for managers
@ -60,7 +61,7 @@ BASE_HEAT_MANAGER = heat_base.HookableMixin
BASE_NOVA_MANAGER = nova_base.HookableMixin BASE_NOVA_MANAGER = nova_base.HookableMixin
BASE_KEYSTONE_MANAGER = keystone_base.Manager BASE_KEYSTONE_MANAGER = keystone_base.Manager
BASE_CINDER_MANAGER = cinder_base.HookableMixin BASE_CINDER_MANAGER = cinder_base.HookableMixin
BASE_TROVE_MANAGER = trove_base.HookableMixin
def get_parser(): def get_parser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -134,6 +135,8 @@ def get_ceilometer_client(**kwargs):
def get_cinder_client(**kwargs): def get_cinder_client(**kwargs):
return cinderclient.Client() return cinderclient.Client()
def get_trove_client(**kwargs):
return troveclient.Client()
CLIENTS = { CLIENTS = {
'nova': get_nova_client, 'nova': get_nova_client,
@ -142,6 +145,7 @@ CLIENTS = {
'cinder': get_cinder_client, 'cinder': get_cinder_client,
'keystone': get_keystone_client, 'keystone': get_keystone_client,
'glance': get_glance_client, 'glance': get_glance_client,
'trove' : get_trove_client,
# 'neutron': get_nova_client # 'neutron': get_nova_client
} }
BASE_MANAGERS = { BASE_MANAGERS = {
@ -151,6 +155,7 @@ BASE_MANAGERS = {
'cinder': BASE_CINDER_MANAGER, 'cinder': BASE_CINDER_MANAGER,
'keystone': BASE_KEYSTONE_MANAGER, 'keystone': BASE_KEYSTONE_MANAGER,
'glance': None, 'glance': None,
'trove': BASE_TROVE_MANAGER,
# 'neutron': BASE_NOVA_MANAGER # 'neutron': BASE_NOVA_MANAGER
} }
NAMESPACES = { NAMESPACES = {