Skip to content

Instantly share code, notes, and snippets.

@mingliangguo
Created July 1, 2025 15:25
Show Gist options
  • Save mingliangguo/1cfe4155901aabb6d7f18d04d886474d to your computer and use it in GitHub Desktop.
Save mingliangguo/1cfe4155901aabb6d7f18d04d886474d to your computer and use it in GitHub Desktop.
list gcp projects with cloud resource manager API
import json
import time
from google.auth import default
from googleapiclient.discovery import build
def search_all_projects(scope: str):
credentials, _ = default()
service = build("cloudasset", "v1", credentials=credentials)
# scope = f"organizations/{org_id}"
asset_types = ["cloudresourcemanager.googleapis.com/Project"]
# filter out prod projects and sys generated (start with sys-)
request = service.v1().searchAllResources(
scope=scope,
assetTypes=asset_types,
query="state:ACTIVE AND NOT labels.environment:prod AND NOT name:sys-",
)
all_projects = []
while request is not None:
response = request.execute()
all_projects.extend(response.get("results", []))
request = service.v1().searchAllResources_next(
previous_request=request, previous_response=response
)
write_file = f"{scope}.json"
with open(write_file, "w", encoding="utf-8") as f:
json.dump(all_projects, f, indent=2, ensure_ascii=False)
return all_projects
def list_gcp_projects(org_id: str):
credentials, _ = default()
service = build("cloudresourcemanager", "v1", credentials=credentials)
# request = service.projects().list(filter=f"parent.type:organization parent.id:{org_id}")
request = service.projects().list(
filter=f"parent.type:folder parent.id:{org_id} AND state:ACTIVE AND NOT labels.cflt_environment:prod"
)
projects = []
while request is not None:
response = request.execute()
projects.extend(response.get("projects", []))
request = service.projects().list_next(
previous_request=request, previous_response=response
)
return projects
def check_name(project_name: str):
"""
Check if the project name contains 'prod', 'non-prod', 'nonprod', or 'preprod'.
"""
return (
"prod" not in project_name.lower()
or "non-prod" in project_name.lower()
or "nonprod" in project_name.lower()
or "preprod" in project_name.lower()
)
if __name__ == "__main__":
# Replace with your actual org ID (numbers only)
# confluent org id
ORG_ID = "123"
FOLDER_ID = "456"
org_scope = f"organizations/{ORG_ID}"
folder_scope = f"folders/{FOLDER_ID}"
start_time = time.time()
print(f"Start searching for projects in org {FOLDER_ID}")
projects = search_all_projects(org_scope)
elapsed = time.time() - start_time
print(f"Execution time: {elapsed:.2f} seconds")
print(f"Found {len(projects)} projects:")
non_sys_projects = [
p
for p in projects
if not (p["name"].split("/"))[-1].startswith("sys-")
and (
not "prod" in (p["name"].split("/"))[-1]
or (
"non-prod" in (p["name"].split("/"))[-1]
or "nonprod" in (p["name"].split("/"))[-1]
or "preprod" in (p["name"].split("/"))[-1]
)
)
]
print(f"Found {len(non_sys_projects)} non system generated projects:")
for project in non_sys_projects:
print(f"- {project['project']} ({project['name']})")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment