Actions\Gateways\Delete's network-unlinking write
(Networks::where('iaas_gateway_id', ...)->update(...)) ran under
Networks' default AuthorizationScope/LimitScope. When this action runs
somewhere AuthorizationScope can't resolve a role for the current
context (e.g. an async queue worker without a re-established
user/account), it falls back to AnonymousRole, which restricts the
query to is_public=true - every VDC network is created is_public=false,
so that update could silently match zero rows, leaving
Networks.iaas_gateway_id pointing at a gateway that's already torn
down. ProvisionGateway's already-has-a-gateway guard then refused
forever, since nothing else ever clears that FK.
Fixes:
- Delete::handle() now bypasses those two scopes on its unlinking
write, matching the same pattern Actions\Networks\Create already
uses for its own internal cleanup query.
- ProvisionGateway::handle()'s guard now actually checks whether the
referenced Gateways row and its underlying VM are alive (bypassing
the same scopes, withTrashed()) before refusing - a stale reference
to an already-deleted gateway/VM gets cleared and provisioning
proceeds normally instead of blocking forever.