Skip to content

Resource Manager

  • Client: google-cloud-resource-manager (resourcemanager_v3.ProjectsClient)
  • Transport: gRPC (the client default). drongo forces the client onto its REST transport for the mock scope.
  • Backend: global namespace (projects are not sharded by an enclosing project).

Use the normal client with no transport argument. Scoped to the Projects API, the most-used part of Resource Manager.

Long-running operations complete synchronously

create_project, delete_project, update_project, and undelete_project return a long-running operation (LRO). drongo completes each one synchronously and returns a done operation, so .result() returns immediately with the Project. Errors surface as REST-style exceptions (a duplicate project raises Conflict).

Create and get a project

create_project assigns a project number; the resource name is projects/<number>. You can address a project by that number or by its project_id:

from drongo import mock_gcp


@mock_gcp
def test_project():
    from google.cloud import resourcemanager_v3 as rm

    client = rm.ProjectsClient()

    created = client.create_project(
        request={"project": {"project_id": "my-app", "display_name": "My App"}}
    ).result()
    assert created.project_id == "my-app"
    assert created.name.startswith("projects/")

    # Addressable by project_id or by projects/<number>.
    assert (
        client.get_project(request={"name": "projects/my-app"}).display_name == "My App"
    )
    assert client.get_project(request={"name": created.name}).project_id == "my-app"

list_projects filters by parent (an organization or folder). search_projects returns active projects:

@mock_gcp
def test_list():
    from google.cloud import resourcemanager_v3 as rm

    client = rm.ProjectsClient()
    client.create_project(
        request={"project": {"project_id": "a", "parent": "folders/42"}}
    ).result()
    client.create_project(
        request={"project": {"project_id": "b", "parent": "folders/42"}}
    ).result()

    listed = client.list_projects(request={"parent": "folders/42"})
    assert sorted(p.project_id for p in listed) == ["a", "b"]

Delete, undelete, update

delete_project moves the project to DELETE_REQUESTED (and hides it from list_projects); undelete_project restores it to ACTIVE:

@mock_gcp
def test_lifecycle():
    from google.cloud import resourcemanager_v3 as rm

    client = rm.ProjectsClient()
    client.create_project(request={"project": {"project_id": "temp"}}).result()

    client.delete_project(request={"name": "projects/temp"}).result()
    assert (
        client.get_project(request={"name": "projects/temp"}).state.name
        == "DELETE_REQUESTED"
    )

    client.undelete_project(request={"name": "projects/temp"}).result()
    assert client.get_project(request={"name": "projects/temp"}).state.name == "ACTIVE"

Coverage

Operation Status
Create / get project Supported
Get by project_id or projects/<number> Supported
List projects (by parent) Supported
Search projects Supported
Delete / undelete project Supported
Update project (display name, labels) Supported
Move project, IAM policy, tags Planned
Folders, Organizations Planned