Repository navigation
Commit eb3cb11
committed
network: use calling account instead of network owner for destroy context
Symptom
-------
Deleting a network whose owning account is disabled fails with:
com.cloud.exception.PermissionDeniedException: Account Account
[{"accountName":"...","id":...}] is disabled.
at com.cloud.acl.DomainChecker.checkAccess(DomainChecker.java:149)
at com.cloud.user.AccountManagerImpl.checkAccess(AccountManagerImpl.java:831)
at com.cloud.network.firewall.FirewallManagerImpl.revokeFirewallRule(FirewallManagerImpl.java:1169)
at com.cloud.network.firewall.FirewallManagerImpl.revokeAllFirewallRulesForNetwork(FirewallManagerImpl.java:1356)
at org.apache.cloudstack.engine.orchestration.NetworkOrchestrator.cleanupNetworkResources(NetworkOrchestrator.java:4192)
at org.apache.cloudstack.engine.orchestration.NetworkOrchestrator.destroyNetwork(NetworkOrchestrator.java:3512)
Root cause
----------
NetworkServiceImpl.deleteNetwork, VpcManagerImpl (private network cleanup),
and KubernetesClusterDestroyWorker each build the ReservationContext used
for destroyNetwork() with the network's *owning* account as the acting
account:
ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
That "owner" account is then propagated all the way into
FirewallManagerImpl.revokeFirewallRule() as the checkAccess() caller when
cleaning up the network's firewall rules. DomainChecker.checkAccess()
unconditionally rejects any caller whose account state isn't ENABLED, so
if the network's owner account happens to be disabled (e.g. while it is
being cleaned up, or simply disabled by an admin without removing it),
network deletion is blocked entirely — even for a root admin performing
the deletion.
By contrast, AccountManagerImpl.cleanupAccount() (the cascade that runs
during full account deletion) already builds this same ReservationContext
with the actual calling account instead of the owner:
ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller);
...which is why account deletion itself was never affected — only a
direct deleteNetwork/VPC-network-cleanup call against a disabled-but-not-
yet-removed account.
Fix
---
Use the actual calling account (the account performing the operation)
instead of the network's owner account when building the
ReservationContext for destroyNetwork(), in all three call sites, matching
the pattern already used by AccountManagerImpl.cleanupAccount().
Reproduced and verified
------------------------
Reproduced end-to-end against a running management server (pre-fix build)
by: creating a test account, creating an isolated network with the
Firewall service and implementing it (deploy a VM), adding firewall rules
on its source-NAT IP, disabling the account, destroying/expunging the VM,
then attempting to delete the network — which failed with the exact same
stack trace as above. Re-enabling the account allowed the same
deleteNetwork call to succeed immediately, confirming the account's
disabled state (via the owner-as-caller path) as the sole cause.1 parent 2974af8 commit eb3cb11
3 files changed
Lines changed: 3 additions & 3 deletions
File tree
- plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers
- server/src/main/java/com/cloud/network
- vpc
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
144 | | - | |
| 144 | + | |
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2924 | 2924 | | |
2925 | 2925 | | |
2926 | 2926 | | |
2927 | | - | |
| 2927 | + | |
2928 | 2928 | | |
2929 | 2929 | | |
2930 | 2930 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2851 | 2851 | | |
2852 | 2852 | | |
2853 | 2853 | | |
2854 | | - | |
| 2854 | + | |
2855 | 2855 | | |
2856 | 2856 | | |
2857 | 2857 | | |
| |||
0 commit comments