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:
parent
c11ef5c435
commit
56e62a5bee
@ -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
|
||||||
]
|
]
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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")
|
||||||
|
32
mistral/tests/unit/actions/openstack/test_trove_generator.py
Normal file
32
mistral/tests/unit/actions/openstack/test_trove_generator.py
Normal 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)
|
@ -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
|
||||||
|
@ -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 = {
|
||||||
|
Loading…
Reference in New Issue
Block a user