Consider the VPNService resource complete if its Neutron object is in PENDING_CREATE

When a Neutron VPN service is created, it starts out in the
PENDING_CREATE state and doesn't hit the ACTIVE status until it has a
matching site-to-site connection.

However, it is required that the OS::Neutron::VPNService resource be
in CREATE_COMPLETE, in order for any dependent
OS::Neutron::IPsecSiteConnection resource to progress to
CREATE_IN_PROGRESS.

Thus, without this change is it is not possible to create a VPNService
resource and a matching IPsecSiteConnection resource in one
stack. Also, if one omits the IPsecSiteConnection resource definition
from the template entirely, the stack can never reach the
CREATE_COMPLETE state on its own, because the VPNService resource
remains perpetually stuck in CREATE_IN_PROGRESS. (This can only be
worked around by creating the site-to-site connection manually, which
isn't the point of orchestration.)

To resolve this catch-22, consider the VPNService resource complete,
even when its underlying Neutron VPN service object is still in
PENDING_CREATE.

Change-Id: I2c8b431265ab92174b5e1efab8a5b4ae673452db
This commit is contained in:
Florian Haas
2025-02-19 11:02:46 +01:00
parent 8dfa34307d
commit 38d80e57b0
3 changed files with 15 additions and 4 deletions

View File

@ -197,9 +197,15 @@ class VPNService(neutron.NeutronResource):
def check_create_complete(self, data):
attributes = self._show_resource()
status = attributes['status']
if status == 'PENDING_CREATE':
return False
elif status == 'ACTIVE':
# The Neutron VPN service doesn't hit the ACTIVE status until
# it has a matching site-to-site connection. However, it is
# required that the VPNService resource be in CREATE_COMPLETE,
# in order for the IPsecSiteConnection resource to progress to
# CREATE_IN_PROGRESS. The only way to resolve this catch-22 is
# to already consider the VPNService resource complete, even
# when its underlying Neutron VPN service object is still in
# PENDING_CREATE.
if status in ['PENDING_CREATE', 'ACTIVE']:
return True
elif status == 'ERROR':
raise exception.ResourceInError(

View File

@ -187,7 +187,6 @@ class VPNServiceTest(common.HeatTestCase):
rsrc = self.create_vpnservice()
self.mockclient.show_vpnservice.side_effect = [
{'vpnservice': {'status': 'PENDING_CREATE'}},
{'vpnservice': {'status': 'ERROR'}},
]

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Enable the creation of an ``OS::Neutron::VPNService`` resource,
and an ``OS::Neutron::IPsecSiteConnection`` resource that depends
on it, within the same stack.