Daniel-Alfasi opened a new issue, #303:
URL: https://github.com/apache/cloudstack-terraform-provider/issues/303

   ### Summary
   
   `terraform import cloudstack_project.<name> <uuid>` fails with a not-found 
error whenever the
   account behind the provider credentials is not a **member** of the project — 
even when that
   account is a Root Admin or Domain Admin that can see the project via 
`listProjects` with
   `listall=true`.
   
   The root cause is that the provider's project lookup never sets the 
`listall` parameter, and the
   CloudStack API default (`listall=false`) makes `listProjects` 
**participant-scoped**: it only
   returns projects the calling account owns or is a member of, regardless of 
the caller's role.
   
   ### Steps to reproduce
   
   1. Have a project `P` owned by account `team-a` in domain `D`.
   2. Configure the provider with credentials of a Root Admin (or Domain Admin 
over `D`) whose
      account is **not** a member of `P`.
   3. Run `terraform import cloudstack_project.p <uuid-of-P>`.
   
   The API-level asymmetry is easy to demonstrate with CloudMonkey using the 
same key pair:
   
       $ cmk list projects id=<uuid-of-P>                # count: 0  
(participant-scoped default)
       $ cmk list projects id=<uuid-of-P> listall=true   # returns the project
   
   ### Expected behavior
   
   The import succeeds: an admin whose role entitles it to see the project via 
`listall=true`
   should be able to import it.
   
   ### Actual behavior
   
   The import fails with a not-found error ("No match found for <uuid>" from 
the lookup /
   "Cannot import non-existent remote object"), because the read path queries 
with the
   participant-scoped default.
   
   ### Root cause
   
   `resourceCloudStackProjectRead` (cloudstack/resource_cloudstack_project.go) 
resolves the project
   via the `getProjectByID` helper, which builds the params with only the id 
(and optionally the
   domain):
   
       p := cs.Project.NewListProjectsParams()
       p.SetId(id)
       ...
       l, err := cs.Project.ListProjects(p)
   
   `listall` is never set, and neither the helper nor the SDK's 
`NewListProjectsParams` applies a
   default, so the request goes out with the API default `listall=false`.
   
   ### Proposed fix
   
   Set `listall=true` on the lookup — the SDK already exposes it:
   
       p := cs.Project.NewListProjectsParams()
       p.SetId(id)
       p.SetListall(true)
   
   This does not widen anyone's privileges: `listall=true` only disables the 
"own/participating
   projects only" default filter, and the management server still enforces the 
caller's role and
   domain-subtree entitlements. Callers who could not see the project before 
will still get
   `count: 0`.
   
   ### Workaround and why it is insufficient
   
   The current workaround is to add the provider's account as a member of every 
project
   (`addAccountToProject`). This is impractical at scale (we hit this with ~90 
projects) and,
   more importantly, **impossible across domains**: CloudStack requires a 
project member account
   to belong to the project's exact domain (`ProjectManagerImpl` looks the 
account up with
   `project.getDomainId()`), and an account cannot exist in more than one 
domain. A Root Admin
   managing projects across several domains therefore has no workaround at all.
   
   ### Environment
   
   - Provider version: latest
   - CloudStack version: latest
   - Terraform version: 1.5.7


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to