mirror of
https://github.com/not-lucky/GeminiKeyManagement.git
synced 2025-12-06 08:44:01 +05:30
implement project creation with random IDs and wait for readiness
This commit is contained in:
83
main.py
83
main.py
@@ -14,6 +14,9 @@ from google_auth_oauthlib.flow import InstalledAppFlow
|
|||||||
from google.cloud import resourcemanager_v3, service_usage_v1, api_keys_v2
|
from google.cloud import resourcemanager_v3, service_usage_v1, api_keys_v2
|
||||||
from google.api_core import exceptions as google_exceptions
|
from google.api_core import exceptions as google_exceptions
|
||||||
from google.auth.transport import requests
|
from google.auth.transport import requests
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import time
|
||||||
|
|
||||||
# --- CONFIGURATION ---
|
# --- CONFIGURATION ---
|
||||||
CREDENTIALS_DIR = "credentials"
|
CREDENTIALS_DIR = "credentials"
|
||||||
@@ -320,6 +323,82 @@ def process_project_for_action(project, creds, action, dry_run, db_lock, account
|
|||||||
logging.info(f"- Finished processing project: {project_id}")
|
logging.info(f"- Finished processing project: {project_id}")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_string(length=10):
|
||||||
|
"""Generates a random alphanumeric string of a given length."""
|
||||||
|
letters_and_digits = string.ascii_lowercase + string.digits
|
||||||
|
return ''.join(random.choice(letters_and_digits) for i in range(length))
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_project_ready(project_id, creds, timeout_seconds=300, initial_delay=5):
|
||||||
|
"""Waits for a newly created project to become fully active."""
|
||||||
|
logging.info(f" Waiting for project {project_id} to become fully active...")
|
||||||
|
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
||||||
|
start_time = time.time()
|
||||||
|
delay = initial_delay
|
||||||
|
|
||||||
|
while time.time() - start_time < timeout_seconds:
|
||||||
|
try:
|
||||||
|
resource_manager.get_project(name=f"projects/{project_id}")
|
||||||
|
logging.info(f" Project {project_id} is now active.")
|
||||||
|
return True
|
||||||
|
except google_exceptions.NotFound:
|
||||||
|
logging.info(f" Project {project_id} not found yet. Retrying in {delay} seconds...")
|
||||||
|
except google_exceptions.PermissionDenied:
|
||||||
|
logging.info(f" Project {project_id} not accessible yet. Retrying in {delay} seconds...")
|
||||||
|
except google_exceptions.GoogleAPICallError as e:
|
||||||
|
logging.warning(f" An API error occurred while waiting for project {project_id}: {e}. Retrying in {delay} seconds...")
|
||||||
|
|
||||||
|
time.sleep(delay)
|
||||||
|
delay = min(delay * 2, 30)
|
||||||
|
|
||||||
|
logging.error(f" Timed out waiting for project {project_id} to become active after {timeout_seconds} seconds.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def create_projects_if_needed(projects, creds, dry_run=False):
|
||||||
|
"""Creates new projects if the account has fewer than 12 projects."""
|
||||||
|
existing_project_count = len(projects)
|
||||||
|
logging.info(f"Found {existing_project_count} existing projects.")
|
||||||
|
newly_created_projects = []
|
||||||
|
|
||||||
|
if existing_project_count >= 12:
|
||||||
|
logging.info("Account already has 12 or more projects. No new projects will be created.")
|
||||||
|
return newly_created_projects
|
||||||
|
|
||||||
|
for i in range(existing_project_count, 12):
|
||||||
|
project_number = str(i + 1).zfill(2)
|
||||||
|
random_string = generate_random_string()
|
||||||
|
project_id = f"project{project_number}-{random_string}"
|
||||||
|
display_name = f"Project{project_number}"
|
||||||
|
|
||||||
|
logging.info(f"Attempting to create project: ID='{project_id}', Name='{display_name}'")
|
||||||
|
|
||||||
|
if dry_run:
|
||||||
|
logging.info(f"[DRY RUN] Would create project '{display_name}' with ID '{project_id}'.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
||||||
|
project_to_create = resourcemanager_v3.Project(
|
||||||
|
project_id=project_id,
|
||||||
|
display_name=display_name
|
||||||
|
)
|
||||||
|
operation = resource_manager.create_project(project=project_to_create)
|
||||||
|
logging.info(f"Waiting for project creation operation for '{display_name}' to complete...")
|
||||||
|
created_project = operation.result()
|
||||||
|
logging.info(f"Successfully created project '{display_name}'.")
|
||||||
|
|
||||||
|
if wait_for_project_ready(project_id, creds):
|
||||||
|
newly_created_projects.append(created_project)
|
||||||
|
else:
|
||||||
|
logging.error(f"Could not confirm project '{display_name}' ({project_id}) became active. It will be skipped.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to create project '{display_name}': {e}")
|
||||||
|
|
||||||
|
return newly_created_projects
|
||||||
|
|
||||||
|
|
||||||
def process_account(email, action, api_keys_data, dry_run=False, max_workers=5):
|
def process_account(email, action, api_keys_data, dry_run=False, max_workers=5):
|
||||||
"""Processes a single account for the given action."""
|
"""Processes a single account for the given action."""
|
||||||
logging.info(f"--- Processing account: {email} for action: {action} ---")
|
logging.info(f"--- Processing account: {email} for action: {action} ---")
|
||||||
@@ -349,6 +428,10 @@ def process_account(email, action, api_keys_data, dry_run=False, max_workers=5):
|
|||||||
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
||||||
projects = list(resource_manager.search_projects())
|
projects = list(resource_manager.search_projects())
|
||||||
|
|
||||||
|
if action == 'create':
|
||||||
|
new_projects = create_projects_if_needed(projects, creds, dry_run)
|
||||||
|
projects.extend(new_projects)
|
||||||
|
|
||||||
if not projects:
|
if not projects:
|
||||||
logging.info(f"No projects found for {email}.")
|
logging.info(f"No projects found for {email}.")
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user