Fix for validating VPN service, Ipsec site connection status

In case of vpn, ipsec site connection resource creation, Stack creation is not
waiting for resource status and returning as stack COMPLETE status.
Following fix validate for create complete.

Change-Id: I99de7759230ca815c12cfae0e90f42ce851be910
Closes-Bug: 1654785
This commit is contained in:
Ashutosh Mishra 2017-01-08 02:40:52 +05:30 committed by Zane Bitter
parent 68526bc0bc
commit 0dbfcbd501
2 changed files with 104 additions and 3 deletions

View File

@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from heat.common import exception
from heat.common.i18n import _
from heat.engine import attributes
from heat.engine import constraints
@ -193,6 +194,22 @@ class VPNService(neutron.NeutronResource):
'vpnservice']
self.resource_id_set(vpnservice['id'])
def check_create_complete(self, data):
attributes = self._show_resource()
status = attributes['status']
if status == 'PENDING_CREATE':
return False
elif status == 'ACTIVE':
return True
elif status == 'ERROR':
raise exception.ResourceInError(
resource_status=status,
status_reason=_('Error in VPNService'))
else:
raise exception.ResourceUnknownStatus(
resource_status=status,
result=_('VPNService creation failed'))
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff:
self.prepare_update_properties(prop_diff)
@ -442,6 +459,23 @@ class IPsecSiteConnection(neutron.NeutronResource):
{'ipsec_site_connection': props})['ipsec_site_connection']
self.resource_id_set(ipsec_site_connection['id'])
def check_create_complete(self, data):
attributes = self._show_resource()
status = attributes['status']
if status == 'PENDING_CREATE':
return False
elif status == 'ACTIVE':
return True
elif status == 'ERROR':
raise exception.ResourceInError(
resource_status=status,
status_reason=_('Error in IPsecSiteConnection'))
else:
raise exception.ResourceUnknownStatus(
resource_status=status,
result=_('IPsecSiteConnection creation failed'))
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff:
self.client().update_ipsec_site_connection(

View File

@ -17,6 +17,7 @@ import mox
from neutronclient.common import exceptions
from neutronclient.neutron import v2_0 as neutronV20
from neutronclient.v2_0 import client as neutronclient
from oslo_config import cfg
import six
from heat.common import exception
@ -156,7 +157,6 @@ class VPNServiceTest(common.HeatTestCase):
del props['router_id']
neutronclient.Client.create_vpnservice(
self.VPN_SERVICE_CONF).AndReturn({'vpnservice': {'id': 'vpn123'}})
self.stack = utils.parse_stack(snippet)
resource_defns = self.stack.t.resource_definitions(self.stack)
return vpnservice.VPNService('vpnservice',
@ -174,6 +174,8 @@ class VPNServiceTest(common.HeatTestCase):
def _test_create(self, resolve_neutron=True, resolve_router=True):
rsrc = self.create_vpnservice(resolve_neutron, resolve_router)
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -184,6 +186,25 @@ class VPNServiceTest(common.HeatTestCase):
self.assertIsNone(rsrc.properties.get(rsrc.ROUTER_ID))
self.m.VerifyAll()
def test_create_failed_error_status(self):
cfg.CONF.set_override('action_retry_limit', 0)
rsrc = self.create_vpnservice()
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'PENDING_CREATE'}})
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ERROR'}})
self.m.ReplayAll()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'ResourceInError: resources.vpnservice: '
'Went to status ERROR due to "Error in VPNService"',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
def test_create_failed(self):
neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client),
@ -218,10 +239,13 @@ class VPNServiceTest(common.HeatTestCase):
self.m.VerifyAll()
def test_delete(self):
rsrc = self.create_vpnservice()
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
neutronclient.Client.delete_vpnservice('vpn123')
neutronclient.Client.show_vpnservice('vpn123').AndRaise(
exceptions.NeutronClientException(status_code=404))
rsrc = self.create_vpnservice()
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
scheduler.TaskRunner(rsrc.delete)()
@ -229,6 +253,8 @@ class VPNServiceTest(common.HeatTestCase):
self.m.VerifyAll()
def test_delete_already_gone(self):
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
neutronclient.Client.delete_vpnservice('vpn123').AndRaise(
exceptions.NeutronClientException(status_code=404))
rsrc = self.create_vpnservice()
@ -239,6 +265,8 @@ class VPNServiceTest(common.HeatTestCase):
self.m.VerifyAll()
def test_delete_failed(self):
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
neutronclient.Client.delete_vpnservice('vpn123').AndRaise(
exceptions.NeutronClientException(status_code=400))
rsrc = self.create_vpnservice()
@ -254,6 +282,8 @@ class VPNServiceTest(common.HeatTestCase):
self.m.VerifyAll()
def test_attribute(self):
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
rsrc = self.create_vpnservice()
neutronclient.Client.show_vpnservice('vpn123').MultipleTimes(
).AndReturn(self.VPN_SERVICE_CONF)
@ -267,6 +297,8 @@ class VPNServiceTest(common.HeatTestCase):
self.m.VerifyAll()
def test_attribute_failed(self):
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
rsrc = self.create_vpnservice()
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
@ -280,6 +312,8 @@ class VPNServiceTest(common.HeatTestCase):
def test_update(self):
rsrc = self.create_vpnservice()
neutronclient.Client.show_vpnservice('vpn123').AndReturn(
{'vpnservice': {'status': 'ACTIVE'}})
self.patchobject(rsrc, 'physical_resource_name',
return_value='VPNService')
@ -351,6 +385,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
def test_create(self):
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -377,11 +413,32 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
def test_create_failed_error_status(self):
cfg.CONF.set_override('action_retry_limit', 0)
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'PENDING_CREATE'}})
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ERROR'}})
self.m.ReplayAll()
error = self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual(
'ResourceInError: resources.ipsec_site_connection: '
'Went to status ERROR due to "Error in IPsecSiteConnection"',
six.text_type(error))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
self.m.VerifyAll()
def test_delete(self):
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
neutronclient.Client.delete_ipsec_site_connection('con123')
neutronclient.Client.show_ipsec_site_connection('con123').AndRaise(
exceptions.NeutronClientException(status_code=404))
rsrc = self.create_ipsec_site_connection()
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
scheduler.TaskRunner(rsrc.delete)()
@ -389,6 +446,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
self.m.VerifyAll()
def test_delete_already_gone(self):
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
neutronclient.Client.delete_ipsec_site_connection('con123').AndRaise(
exceptions.NeutronClientException(status_code=404))
rsrc = self.create_ipsec_site_connection()
@ -399,6 +458,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
self.m.VerifyAll()
def test_delete_failed(self):
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
neutronclient.Client.delete_ipsec_site_connection('con123').AndRaise(
exceptions.NeutronClientException(status_code=400))
rsrc = self.create_ipsec_site_connection()
@ -415,6 +476,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
def test_attribute(self):
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
neutronclient.Client.show_ipsec_site_connection(
'con123').MultipleTimes().AndReturn(
self.IPSEC_SITE_CONNECTION_CONF)
@ -438,6 +501,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
def test_attribute_failed(self):
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
error = self.assertRaises(exception.InvalidTemplateAttribute,
@ -450,6 +515,8 @@ class IPsecSiteConnectionTest(common.HeatTestCase):
def test_update(self):
rsrc = self.create_ipsec_site_connection()
neutronclient.Client.show_ipsec_site_connection('con123').AndReturn(
{'ipsec_site_connection': {'status': 'ACTIVE'}})
neutronclient.Client.update_ipsec_site_connection(
'con123', {'ipsec_site_connection': {'admin_state_up': False}})
self.m.ReplayAll()