mirror of
https://github.com/not-lucky/GeminiKeyManagement.git
synced 2025-12-06 08:44:01 +05:30
allow deletion of keys
This commit is contained in:
35
README.md
35
README.md
@@ -1,6 +1,6 @@
|
||||
# Gemini Key Management
|
||||
|
||||
This script automates the process of creating Google Cloud API keys for the Generative Language API (Gemini) across multiple Google Cloud projects.
|
||||
This script automates the process of creating and deleting Google Cloud API keys for the Generative Language API (Gemini) across multiple Google Cloud projects.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -20,19 +20,26 @@ This script automates the process of creating Google Cloud API keys for the Gene
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
*(Note: A `requirements.txt` file will be generated in a later step)*
|
||||
|
||||
3. **Create `emails.txt` file:**
|
||||
3. **Create `emails.txt` file (for creating keys in bulk):**
|
||||
- Create a file named `emails.txt` in the root of the project.
|
||||
- Add the email addresses of the Google accounts you want to process, one email per line.
|
||||
- Add the email addresses of the Google accounts you want to process, one email per line. You can add comments with `#`.
|
||||
|
||||
## Usage
|
||||
|
||||
Run the script from your terminal:
|
||||
Run the script from your terminal with a specified action (`create` or `delete`).
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
### Creating API Keys
|
||||
|
||||
- **For all users in `emails.txt`:**
|
||||
```bash
|
||||
python main.py create
|
||||
```
|
||||
|
||||
- **For a single user:**
|
||||
```bash
|
||||
python main.py create --email your.email@example.com
|
||||
```
|
||||
|
||||
The first time you run the script for a new email address, you will be prompted to authenticate with your Google account in your web browser. A token file will be saved in the `credentials` directory for future runs.
|
||||
|
||||
@@ -40,4 +47,14 @@ The script will then:
|
||||
- Find all Google Cloud projects accessible by the authenticated user.
|
||||
- Enable the `generativelanguage.googleapis.com` API for each project.
|
||||
- Create a new API key named "Gemini API Key" with restrictions to the Generative Language API.
|
||||
- Save the API key to a file named `<email>.key`.
|
||||
- Save the API key(s) to a file named `<email>.keys.txt`.
|
||||
|
||||
### Deleting API Keys
|
||||
|
||||
To delete all API keys with the display name "Gemini API Key" for a specific user, run:
|
||||
|
||||
```bash
|
||||
python main.py delete --email your.email@example.com
|
||||
```
|
||||
|
||||
This will iterate through all projects accessible by that user and remove the matching keys.
|
||||
|
||||
103
main.py
103
main.py
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import google.auth
|
||||
from google.oauth2.credentials import Credentials
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
@@ -18,16 +19,22 @@ SCOPES = [
|
||||
]
|
||||
|
||||
def load_emails_from_file(filename):
|
||||
"""Loads a list of emails from a text file."""
|
||||
"""Loads a list of emails from a text file, ignoring comments."""
|
||||
if not os.path.exists(filename):
|
||||
print(f"Error: Email file not found at '{filename}'")
|
||||
print("Please create it and add one email address per line.")
|
||||
return []
|
||||
with open(filename, "r") as f:
|
||||
# Ignore empty lines and lines starting with #
|
||||
return [line.strip() for line in f if line.strip() and not line.startswith("#")]
|
||||
|
||||
def main():
|
||||
"""Main function to orchestrate API key creation."""
|
||||
"""Main function to orchestrate API key creation or deletion."""
|
||||
parser = argparse.ArgumentParser(description="Manage Gemini API keys in Google Cloud projects.")
|
||||
parser.add_argument("action", choices=['create', 'delete'], help="The action to perform: 'create' or 'delete' API keys.")
|
||||
parser.add_argument("--email", help="Specify a single email address to process. Required for 'delete' action. If not provided for 'create', emails will be read from emails.txt.")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.exists(CLIENT_SECRETS_FILE):
|
||||
print(f"Error: OAuth client secrets file not found at '{CLIENT_SECRETS_FILE}'")
|
||||
print("Please follow the setup instructions in README.md to create it.")
|
||||
@@ -36,39 +43,56 @@ def main():
|
||||
if not os.path.exists(CREDENTIALS_DIR):
|
||||
os.makedirs(CREDENTIALS_DIR)
|
||||
|
||||
emails = load_emails_from_file(EMAILS_FILE)
|
||||
if not emails:
|
||||
emails_to_process = []
|
||||
if args.email:
|
||||
emails_to_process.append(args.email)
|
||||
elif args.action == 'delete':
|
||||
print("Error: The 'delete' action requires the --email argument.")
|
||||
sys.exit(1)
|
||||
else: # action is 'create' and no email provided
|
||||
emails_to_process = load_emails_from_file(EMAILS_FILE)
|
||||
if not emails_to_process:
|
||||
print("No emails found in emails.txt. Exiting.")
|
||||
sys.exit(1)
|
||||
|
||||
for email in emails:
|
||||
print(f"--- Processing account: {email} ---")
|
||||
creds = get_credentials_for_email(email)
|
||||
if not creds:
|
||||
print(f"Could not get credentials for {email}. Skipping.")
|
||||
continue
|
||||
for email in emails_to_process:
|
||||
process_account(email, args.action)
|
||||
|
||||
try:
|
||||
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
||||
projects = list(resource_manager.search_projects()) # Convert iterator to list
|
||||
def process_account(email, action):
|
||||
"""Processes a single account for the given action."""
|
||||
print(f"--- Processing account: {email} for action: {action} ---")
|
||||
creds = get_credentials_for_email(email)
|
||||
if not creds:
|
||||
print(f"Could not get credentials for {email}. Skipping.")
|
||||
return
|
||||
|
||||
if not projects:
|
||||
print(f"No projects found for {email}.")
|
||||
continue
|
||||
try:
|
||||
resource_manager = resourcemanager_v3.ProjectsClient(credentials=creds)
|
||||
projects = list(resource_manager.search_projects())
|
||||
|
||||
print(f"Found {len(projects)} projects. Processing...")
|
||||
for project in projects:
|
||||
project_id = project.project_id
|
||||
print(f"- Project: {project_id}")
|
||||
if not projects:
|
||||
print(f"No projects found for {email}.")
|
||||
return
|
||||
|
||||
print(f"Found {len(projects)} projects. Processing...")
|
||||
for project in projects:
|
||||
project_id = project.project_id
|
||||
print(f"- Project: {project_id}")
|
||||
|
||||
if action == 'create':
|
||||
if enable_api(project_id, creds):
|
||||
key = create_api_key(project_id, creds)
|
||||
if key:
|
||||
save_api_key(email, project_id, key.key_string)
|
||||
elif action == 'delete':
|
||||
delete_api_keys(project_id, creds)
|
||||
|
||||
except google_exceptions.PermissionDenied as err:
|
||||
print(f"Permission denied for account {email}. Check IAM roles.")
|
||||
print(f" Error: {err}")
|
||||
except google_exceptions.GoogleAPICallError as err:
|
||||
print(f"An API error occurred while processing account {email}: {err}")
|
||||
|
||||
except google_exceptions.PermissionDenied as err:
|
||||
print(f"Permission denied for account {email}. Check IAM roles.")
|
||||
print(f" Error: {err}")
|
||||
except google_exceptions.GoogleAPICallError as err:
|
||||
print(f"An API error occurred while processing account {email}: {err}")
|
||||
|
||||
def get_credentials_for_email(email):
|
||||
"""Handles the OAuth2 flow for a given email."""
|
||||
@@ -153,6 +177,35 @@ def create_api_key(project_id, credentials):
|
||||
print(f"Error creating API key for project {project_id}: {err}")
|
||||
return None
|
||||
|
||||
def delete_api_keys(project_id, credentials):
|
||||
"""Deletes all API keys with the display name 'Gemini API Key'."""
|
||||
try:
|
||||
api_keys_client = api_keys_v2.ApiKeysClient(credentials=credentials)
|
||||
parent = f"projects/{project_id}/locations/global"
|
||||
|
||||
keys = api_keys_client.list_keys(parent=parent)
|
||||
keys_to_delete = [key for key in keys if key.display_name == "Gemini API Key"]
|
||||
|
||||
if not keys_to_delete:
|
||||
print(f" No 'Gemini API Key' found to delete.")
|
||||
return
|
||||
|
||||
print(f" Found {len(keys_to_delete)} key(s) with display name 'Gemini API Key'. Deleting...")
|
||||
for key in keys_to_delete:
|
||||
try:
|
||||
request = api_keys_v2.DeleteKeyRequest(name=key.name)
|
||||
operation = api_keys_client.delete_key(request=request)
|
||||
operation.result() # Wait for completion
|
||||
print(f" Successfully deleted key: {key.uid}")
|
||||
except google_exceptions.GoogleAPICallError as err:
|
||||
print(f" Error deleting key {key.uid}: {err}")
|
||||
|
||||
except google_exceptions.PermissionDenied as err:
|
||||
print(f" Permission denied to list or delete API keys for project {project_id}. Skipping.")
|
||||
except google_exceptions.GoogleAPICallError as err:
|
||||
print(f" An API error occurred while deleting keys for project {project_id}: {err}")
|
||||
|
||||
|
||||
def save_api_key(email, project_id, api_key):
|
||||
"""Saves the API key to a file, including the project ID."""
|
||||
filename = f"{email}.keys.txt"
|
||||
|
||||
Reference in New Issue
Block a user