From d8193fca04085988eae09f52a68629d0f9114136 Mon Sep 17 00:00:00 2001 From: Alijohn Ghassemlouei Date: Fri, 28 Aug 2026 11:42:14 -0400 Subject: [PATCH 1/4] fix(gem4gov-cli): remove duplicate license command group (#110) --- .../gemini-enterprise/gem4gov-cli/gem4gov.py | 108 ------------------ 1 file changed, 108 deletions(-) diff --git a/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py b/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py index d324c5ca8..4aaf5061f 100644 --- a/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py +++ b/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py @@ -771,114 +771,6 @@ def distribute_licenses(billing_account, config_id, target_project_number, locat except Exception as e: click.echo(f"An unexpected error occurred: {e}") -############################################################## -################ gem4gov license ################ -############################################################## - -@cli.group() -def license(): - """Manages Gemini for Government licenses.""" - pass - -@license.command(name='list') -@click.option('--billing-account', required=True, help='The billing account ID.') -@click.option('--quota-project', required=False, help='The project ID to use for API quota.') -@click.option('--format', type=click.Choice(['text', 'json']), default='text', help='The output format.') -def list_licenses(billing_account, quota_project, format): - """Lists available Gemini for Government license configurations for a billing account.""" - credentials = get_credentials() - if quota_project: - credentials = credentials.with_quota_project(quota_project) - - # Use discoveryengine v1alpha as per PDF - client_options = ClientOptions(api_endpoint="https://us-discoveryengine.googleapis.com") - service = build('discoveryengine', 'v1alpha', credentials=credentials, client_options=client_options) - - try: - request = service.billingAccounts().billingAccountLicenseConfigs().list( - parent=f'billingAccounts/{billing_account}' - ) - response = request.execute() - - configs = response.get('billingAccountLicenseConfigs', []) - - if format == 'json': - click.echo(json.dumps(configs, indent=2)) - return - - if not configs: - click.echo(f"No license configurations found for billing account {billing_account}.") - return - - for config in configs: - name = config.get('subscriptionDisplayName', config.get('name')) - total = config.get('licenseCount', 0) - distributions = config.get('licenseConfigDistributions', {}) - distributed = sum(int(v) for v in distributions.values()) - available = int(total) - distributed - - # Extract ID from name: billingAccounts/ID/billingAccountLicenseConfigs/CONFIG_ID - config_id = config.get('name').split('/')[-1] - - click.echo(f"Subscription: {name}") - click.echo(f" ID: {config_id}") - click.echo(f" Total Licenses: {total}") - click.echo(f" Distributed: {distributed}") - click.echo(f" Available: {available}") - click.echo("---") - - except HttpError as e: - click.echo(f"An error occurred: {e}") - except Exception as e: - click.echo(f"An unexpected error occurred: {e}") - -@license.command(name='distribute') -@click.option('--billing-account', required=True, help='The billing account ID.') -@click.option('--config-id', required=True, help='The billing account license config ID.') -@click.option('--target-project-number', required=True, help='The target project number.') -@click.option('--location', default='global', type=click.Choice(['global', 'us', 'eu']), help='The location.') -@click.option('--count', required=True, type=int, help='The number of licenses to distribute (incremental).') -@click.option('--license-config-id', help='The existing project-level license config ID (optional).') -@click.option('--quota-project', required=False, help='The project ID to use for API quota.') -def distribute_licenses(billing_account, config_id, target_project_number, location, count, license_config_id, quota_project): - """Distributes Gemini for Government licenses to a project.""" - credentials = get_credentials() - if quota_project: - credentials = credentials.with_quota_project(quota_project) - - endpoint = "https://discoveryengine.googleapis.com" - if location == 'us': - endpoint = "https://us-discoveryengine.googleapis.com" - elif location == 'eu': - endpoint = "https://eu-discoveryengine.googleapis.com" - - client_options = ClientOptions(api_endpoint=endpoint) - # v1alpha is needed for billingAccountLicenseConfigs - service = build('discoveryengine', 'v1alpha', credentials=credentials, client_options=client_options) - - name = f'billingAccounts/{billing_account}/billingAccountLicenseConfigs/{config_id}' - - body = { - "projectNumber": target_project_number, - "location": location, - "licenseCount": count - } - if license_config_id: - body["licenseConfigId"] = license_config_id - - try: - request = service.billingAccounts().billingAccountLicenseConfigs().distributeLicenseConfig( - name=name, - body=body - ) - response = request.execute() - click.echo("Licenses distributed successfully!") - click.echo(json.dumps(response, indent=2)) - - except HttpError as e: - click.echo(f"An error occurred: {e}") - except Exception as e: - click.echo(f"An unexpected error occurred: {e}") From 13ae321776c4dc0240c7a957641f062f42dc4425 Mon Sep 17 00:00:00 2001 From: Alijohn Ghassemlouei Date: Fri, 28 Aug 2026 11:42:26 -0400 Subject: [PATCH 2/4] fix(gem4gov-cli): clarify onboard data store prompt to not require pre-loaded data (#144) --- .../fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py b/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py index 4aaf5061f..2de3cb3fd 100644 --- a/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py +++ b/blueprints/fedramp-high/gemini-enterprise/gem4gov-cli/gem4gov.py @@ -258,7 +258,7 @@ def onboard(): sys.exit(1) click.echo(click.style(f"Gemini Enterprise data stores allow end-users to search and ask questions based on a variety of first and third-party datasets. Currently, the only data stores that are available in Gemini for Governement customers are: {supported_data_stores}", fg='yellow')) while True: - if click.confirm('Do you have an existing data store(s) already created and loaded with data?'): + if click.confirm('Do you have an existing data store(s) already created?'): # User specified they have existing data stores data_store_input = click.prompt('Please enter a comma-separated list of data stores that you would like to connect to Gemini Enterprise', type=str).strip() data_store_list = [item.strip() for item in data_store_input.split(',')] From 1cabebcf74b5b69e0373c881150cd8abe2c1139a Mon Sep 17 00:00:00 2001 From: Alijohn Ghassemlouei Date: Fri, 28 Aug 2026 11:42:42 -0400 Subject: [PATCH 3/4] fix(gemini-stage-1): remove deprecated gemini_config_id from terraform.tfvars.sample (#175) --- .../gemini-enterprise/gemini-stage-1/terraform.tfvars.sample | 3 --- 1 file changed, 3 deletions(-) diff --git a/blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/terraform.tfvars.sample b/blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/terraform.tfvars.sample index 57d72389b..b0f530cb5 100644 --- a/blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/terraform.tfvars.sample +++ b/blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/terraform.tfvars.sample @@ -19,8 +19,5 @@ stage_0_state_bucket = "sedev-gemini-enterprise-tf-state-sedev-test-mike-iac-cor # This domain will point to the Load Balancer's IP Address gemini_enterprise_domain = "gemini.yourdomain.gov" -# Gemini Enterprise Config ID (Output from Gem4Gov CLI) -gemini_config_id = "your_gemini_config_id" - # Google Cloud Self-Managed SSL Cert Name (Pre-uploaded to Google Cloud Certificate Manager) ssl_certificate_name = "your-cert-name-here" \ No newline at end of file From 5975e67984ad4aa5aa5b236cbf21ef1361b2191e Mon Sep 17 00:00:00 2001 From: Alijohn Ghassemlouei Date: Fri, 28 Aug 2026 11:42:50 -0400 Subject: [PATCH 4/4] fix(gemini-stage-0): remove unused kms_project_id and us_keyring_name variables (#176) --- .../gemini-enterprise/gemini-stage-0/variables.tf | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf b/blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf index d9380cfb0..5a1f5bb94 100644 --- a/blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf +++ b/blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf @@ -34,17 +34,6 @@ variable "compliance_regime" { } } -variable "kms_project_id" { - description = "The Project ID where CMEK keys are stored." - type = string -} - -variable "us_keyring_name" { - description = "The name of the US Multi-Region KeyRing (if existing). If empty, one will be created." - type = string - default = "" -} - variable "domain" { description = "FQDN for the load-balancer hosted apps, where the subdomain will be prepended to." type = string