Created
July 1, 2025 15:25
-
-
Save mingliangguo/1cfe4155901aabb6d7f18d04d886474d to your computer and use it in GitHub Desktop.
list gcp projects with cloud resource manager API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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