Refactor repeated handle_delete

Add parent handle_delete method based on entity
argument and remove all repeated occurrences in
Resource children.

Change-Id: Ic18708e3780721031ccbba61f2d949be7b837ca3
This commit is contained in:
Peter Razumovsky 2015-08-17 17:22:46 +03:00
parent 87e625e20c
commit 0a5ce7d27b
26 changed files with 40 additions and 193 deletions

View File

@ -10,6 +10,7 @@
# 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 six
from heat.engine.clients import client_plugin
@ -30,3 +31,8 @@ class BarbicanClientPlugin(client_plugin.ClientPlugin):
session=self._keystone_session, endpoint=endpoint)
return client
def is_not_found(self, ex):
# This is the only exception the client raises
# Inspecting the message to see if it's a 'Not Found'
return 'Not Found' in six.text_type(ex)

View File

@ -1146,6 +1146,17 @@ class Resource(object):
with excutils.save_and_reraise_exception():
self._release(engine_id)
def handle_delete(self):
"""Default implementation; should be overridden by resources."""
if self.entity and self.resource_id is not None:
try:
obj = getattr(self.client(), self.entity)
obj.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
return None
return self.resource_id
@scheduler.wrappertask
def delete(self):
'''

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine import attributes
@ -189,19 +187,6 @@ class Order(resource.Resource):
return order.status == 'ACTIVE'
def handle_delete(self):
if not self.resource_id:
return
client = self.client()
try:
client.orders.delete(self.resource_id)
except Exception as exc:
# This is the only exception the client raises
# Inspecting the message to see if it's a 'Not Found'
if 'Not Found' not in six.text_type(exc):
raise
def _resolve_attribute(self, name):
client = self.client()
order = client.orders.get(self.resource_id)

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common.i18n import _
from heat.engine import attributes
from heat.engine import constraints
@ -116,19 +114,6 @@ class Secret(resource.Resource):
self.resource_id_set(secret_ref)
return secret_ref
def handle_delete(self):
if not self.resource_id:
return
client = self.client()
try:
client.secrets.delete(self.resource_id)
except Exception as exc:
# This is the only exception the client raises
# Inspecting the message to see if it's a 'Not Found'
if 'Not Found' not in six.text_type(exc):
raise
def _resolve_attribute(self, name):
secret = self.client().secrets.get(self.resource_id)

View File

@ -372,11 +372,7 @@ class CeilometerAlarm(resource.Resource):
except exception.WatchRuleNotFound:
pass
if self.resource_id is not None:
try:
self.client().alarms.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
super(CeilometerAlarm, self).handle_delete()
def handle_check(self):
watch_name = self.physical_resource_name()
@ -424,12 +420,6 @@ class BaseCeilometerAlarm(resource.Resource):
self.client().alarms.update(
alarm_id=self.resource_id, enabled=True)
def handle_delete(self):
try:
self.client().alarms.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def handle_check(self):
self.client().alarms.get(self.resource_id)

View File

@ -30,6 +30,8 @@ class CinderEncryptedVolumeType(resource.Resource):
default_client_name = 'cinder'
entity = 'volume_encryption_types'
PROPERTIES = (
PROVIDER, CONTROL_LOCATION, CIPHER, KEY_SIZE, VOLUME_TYPE
) = (
@ -106,14 +108,6 @@ class CinderEncryptedVolumeType(resource.Resource):
volume_type=self.resource_id, specs=prop_diff
)
def handle_delete(self):
if self.resource_id is None:
return
try:
self.client().volume_encryption_types.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
def resource_mapping():
return {

View File

@ -96,15 +96,6 @@ class CinderVolumeType(resource.Resource):
if new_keys is not None:
volume_type.set_keys(new_keys)
def handle_delete(self):
if self.resource_id is None:
return
try:
self.client().volume_types.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
# TODO(huangtianhua): remove this method when bug #1479641 is fixed.
def _show_resource(self):
vtype = self.client().volume_types.get(self.resource_id)

View File

@ -77,6 +77,8 @@ class DesignateDomain(resource.Resource):
default_client_name = 'designate'
entity = 'domains'
def handle_create(self):
args = dict(
name=self.properties[self.NAME],
@ -105,13 +107,6 @@ class DesignateDomain(resource.Resource):
args['id'] = self.resource_id
self.client_plugin().domain_update(**args)
def handle_delete(self):
if self.resource_id is not None:
try:
self.client().domains.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def _resolve_attribute(self, name):
if name == self.SERIAL:
domain = self.client().domains.get(self.resource_id)

View File

@ -114,15 +114,6 @@ class GlanceImage(resource.Resource):
image = self.client().images.get(image_id)
return image.status == 'active'
def handle_delete(self):
if self.resource_id is None:
return
try:
self.client().images.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def _show_resource(self):
if self.glance().version == 1.0:
return super(GlanceImage, self)._show_resource()

View File

@ -136,14 +136,6 @@ class BayModel(resource.Resource):
bm = self.client().baymodels.create(**args)
self.resource_id_set(bm.uuid)
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().baymodels.delete(self.resource_id)
except Exception as exc:
self.client_plugin().ignore_not_found(exc)
def resource_mapping():
return {

View File

@ -97,15 +97,6 @@ class SecurityService(resource.Resource):
self.client().security_services.update(self.resource_id,
**prop_diff)
def handle_delete(self):
if self.resource_id is None:
return
try:
self.client().security_services.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def resource_mapping():
return {

View File

@ -260,15 +260,6 @@ class ManilaShare(resource.Resource):
raise resource.ResourceUnknownStatus(status_reason=reason,
resource_status=share_status)
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().shares.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def check_delete_complete(self, *args):
if not self.resource_id:
return True

View File

@ -164,12 +164,6 @@ class ManilaShareNetwork(resource.Resource):
nova_net_id=prop_diff.get(self.NOVA_NETWORK),
description=prop_diff.get(self.DESCRIPTION))
def handle_delete(self):
try:
self.client().share_networks.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def resource_mapping():
return {'OS::Manila::ShareNetwork': ManilaShareNetwork}

View File

@ -87,15 +87,6 @@ class ManilaShareType(resource.Resource):
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 {

View File

@ -110,15 +110,6 @@ class CronTrigger(resource.Resource):
cron_trigger = self.client().cron_triggers.create(**args)
self.resource_id_set(cron_trigger.name)
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().cron_triggers.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
def _resolve_attribute(self, name):
try:
trigger = self.client().cron_triggers.get(self.resource_id)

View File

@ -130,15 +130,6 @@ class NovaFlavor(resource.Resource):
if new_keys is not None:
flavor.set_keys(new_keys)
def handle_delete(self):
if self.resource_id is None:
return
try:
self.client().flavors.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
def resource_mapping():
return {

View File

@ -86,13 +86,6 @@ class NovaFloatingIp(resource.Resource):
self.resource_id_set(floating_ip.id)
self._floating_ip = floating_ip
def handle_delete(self):
if self.resource_id is not None:
try:
self.client().floating_ips.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
def _resolve_attribute(self, key):
floating_ip = self._get_resource()
attributes = {

View File

@ -121,13 +121,6 @@ class KeyPair(resource.Resource):
True)
self.resource_id_set(new_keypair.id)
def handle_delete(self):
if self.resource_id:
try:
self.client().keypairs.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
def handle_check(self):
self.client().keypairs.get(self.resource_id)

View File

@ -60,13 +60,6 @@ class ServerGroup(resource.Resource):
policies=policies)
self.resource_id_set(server_group.id)
def handle_delete(self):
if self.resource_id:
try:
self.client().server_groups.delete(self.resource_id)
except Exception as e:
self.client_plugin().ignore_not_found(e)
def physical_resource_name(self):
name = self.properties[self.NAME]
if name:

View File

@ -118,6 +118,8 @@ class SaharaCluster(resource.Resource):
default_client_name = 'sahara'
entity = 'clusters'
def _validate_depr_keys(self, properties, key, depr_key):
value = properties.get(key)
depr_value = properties.get(depr_key)
@ -181,18 +183,6 @@ class SaharaCluster(resource.Resource):
LOG.info(_LI("Cluster '%s' has been created"), cluster.name)
return True
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().clusters.delete(self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
return None
return self.resource_id
def check_delete_complete(self, resource_id):
if not resource_id:
return True

View File

@ -161,6 +161,8 @@ class SaharaNodeGroupTemplate(resource.Resource):
physical_resource_name_limit = 50
entity = 'node_group_templates'
def _ngt_name(self):
name = self.properties[self.NAME]
if name:
@ -210,17 +212,6 @@ class SaharaNodeGroupTemplate(resource.Resource):
self.resource_id_set(node_group_template.id)
return self.resource_id
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().node_group_templates.delete(
self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
LOG.info(_LI("Node Group Template '%s' has been deleted."),
self._ngt_name())
def validate(self):
res = super(SaharaNodeGroupTemplate, self).validate()
if res:
@ -350,6 +341,8 @@ class SaharaClusterTemplate(resource.Resource):
physical_resource_name_limit = 50
entity = 'cluster_templates'
def _cluster_template_name(self):
name = self.properties[self.NAME]
if name:
@ -387,17 +380,6 @@ class SaharaClusterTemplate(resource.Resource):
self.resource_id_set(cluster_template.id)
return self.resource_id
def handle_delete(self):
if not self.resource_id:
return
try:
self.client().cluster_templates.delete(
self.resource_id)
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
LOG.info(_LI("Cluster Template '%s' has been deleted."),
self._cluster_template_name())
def validate(self):
res = super(SaharaClusterTemplate, self).validate()
if res:

View File

@ -119,7 +119,10 @@ class CinderVolumeTypeTest(common.HeatTestCase):
volume_type_id = '927202df-1afb-497f-8368-9c2d2f26e5db'
self.my_volume_type.resource_id = volume_type_id
self.volume_types.delete.return_value = None
self.assertIsNone(self.my_volume_type.handle_delete())
self.assertEqual('927202df-1afb-497f-8368-9c2d2f26e5db',
self.my_volume_type.handle_delete())
def test_volume_type_handle_delete_not_found(self):
exc = self.cinderclient.HTTPClientError('Not Found.')
self.volume_types.delete.side_effect = exc
self.assertIsNone(self.my_volume_type.handle_delete())

View File

@ -109,7 +109,8 @@ class CinderEncryptedVolumeTypeTest(common.HeatTestCase):
volume_type_id = '01bd581d-33fe-4d6d-bd7b-70ae076d39fb'
self.my_encrypted_vol_type.resource_id = volume_type_id
self.volume_encryption_types.delete.return_value = None
self.assertIsNone(self.my_encrypted_vol_type.handle_delete())
self.assertEqual('01bd581d-33fe-4d6d-bd7b-70ae076d39fb',
self.my_encrypted_vol_type.handle_delete())
def test_handle_delete_rsrc_not_found(self):
exc = self.cinderclient.HTTPClientError('Not Found.')

View File

@ -90,7 +90,8 @@ class NovaFlavorTest(common.HeatTestCase):
flavor_id = '927202df-1afb-497f-8368-9c2d2f26e5db'
self.my_flavor.resource_id = flavor_id
self.flavors.delete.return_value = None
self.assertIsNone(self.my_flavor.handle_delete())
self.assertEqual('927202df-1afb-497f-8368-9c2d2f26e5db',
self.my_flavor.handle_delete())
self.flavors.delete.side_effect = fakes.fake_exception()
self.assertIsNone(self.my_flavor.handle_delete())

View File

@ -131,7 +131,8 @@ class DesignateDomainTest(common.HeatTestCase):
self.test_resource.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
mock_domain_delete.return_value = None
self.assertIsNone(self.test_resource.handle_delete())
self.assertEqual('477e8273-60a7-4c41-b683-fdb0bc7cd151',
self.test_resource.handle_delete())
mock_domain_delete.assert_called_once_with(
self.test_resource.resource_id
)

View File

@ -192,7 +192,8 @@ class GlanceImageTest(common.HeatTestCase):
image_id = '41f0e60c-ebb4-4375-a2b4-845ae8b9c995'
self.my_image.resource_id = image_id
self.images.delete.return_value = None
self.assertIsNone(self.my_image.handle_delete())
self.assertEqual('41f0e60c-ebb4-4375-a2b4-845ae8b9c995',
self.my_image.handle_delete())
self.images.delete.side_effect = glance_exceptions.HTTPNotFound(404)
self.assertIsNone(self.my_image.handle_delete())