diff --git a/modules/agent-engine/README.md b/modules/agent-engine/README.md index f886a4972..eba288e52 100644 --- a/modules/agent-engine/README.md +++ b/modules/agent-engine/README.md @@ -2,13 +2,16 @@ The module creates Agent Engine and related dependencies. -- It can automatically generate and update the Pickle file for you, given a source file. -- It optionally creates a GCS storage bucket or can use an existing one and loads on it all your dependencies (`pickle`, `dependencies.tar.gz`, `requirements.txt`) -- Manages the service accounts lifecycle +- It supports both source based deployments (aka in-line deployment) and serialized object deployment (aka pickle deployment). +- For serialized object deployment, it optionally creates a GCS storage bucket or can use an existing one and loads on it all your dependencies (`pickle`, `dependencies.tar.gz`, `requirements.txt`). +- Manages custom service accounts lifecycle. -- [Packaging dependencies](#packaging-dependencies) -- [Minimal deployment](#minimal-deployment) +- [Source based deployment](#source-based-deployment) + - [Create the tar.gz package](#create-the-targz-package) + - [Minimal deployment](#minimal-deployment) +- [Serialized Object Deployment](#serialized-object-deployment) + - [Unmanaged deployments](#unmanaged-deployments) - [Service accounts](#service-accounts) - [Specify an encryption key](#specify-an-encryption-key) - [Define environment variables and use secrets](#define-environment-variables-and-use-secrets) @@ -17,20 +20,20 @@ The module creates Agent Engine and related dependencies. - [Outputs](#outputs) -## Packaging dependencies +## Source based deployment -To deploy an agent, you first need package your dependencies. This consists of a folder with +The source based deployment is the newest, most efficient and easiest way to deploy your agents. -- The source Python file defining your agent to be pickled (or the equivalent pickle file). -- The `dependencies.tar.gz`. +### Create the tar.gz package + +First, create a *tar.gz* file with these files: + +- The source Python file defining your agent, called `agent.py`. - The `requirements.txt` file. -By default, the module expects these files to be in an `src` subfolder. +By default, the module expects the `tar.gz` file to be in the `src` subfolder and to be called `source.tar.gz`. -You can decide to **let the module create the pickle file for you**, starting from a source agent file. -In this case, the module expects you to have in `src` a source file called `agent.py` with a variable referencing your agent function definition called `local_agent`. - -This is an example of `agent.py` file for ADK: +This is an example of an `agent.py` file for ADK: ```python from google.adk.agents import LlmAgent @@ -55,19 +58,12 @@ root_agent = LlmAgent( tools=[get_exchange_rate], ) -local_agent = AdkApp(agent=root_agent) +agent = AdkApp(agent=root_agent) ``` -The [tools/serialize_agent.py](tools/serialize_agent.py) is used to generate the `pickle.pkl` file. -You module needs [these packages](tools/requirements.txt) to work. +### Minimal deployment -If you **already have a pickle file**, the module expects you to have in the `src` subfolder a `pickle.pkl` file. - -You can customize these values by using the `source_files` variable. - -## Minimal deployment - -This example assumes you are providing the [source packages](#packaging-dependencies) (`agent.py`, `dependencies.tar.gz` and `requirements.txt`) in the `src` subfolder. Every time you will change the agent definition, the module will generate the new pickle file for you, will update it on the GCS bucket and will update your agent. +You can now deploy the agent. ```hcl module "agent_engine" { @@ -80,34 +76,71 @@ module "agent_engine" { agent_framework = "google-adk" } - source_files = { - path = "assets/src/" + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } } } # tftest inventory=minimal.yaml ``` -Alternatively, you can pass a pre-generated `pickle.pkl` file. +You can change the name of the tar.gz package, of the requirement file, the name of the Python file and the name of the agent function by using the `deployment_files.source_config` variable. + +## Serialized Object Deployment + +You can also manually serialize your agent by using the [cloudpickle library](https://github.com/cloudpipe/cloudpickle) and pass the `pickle.pkl`, `dependencies.tar.gz` and `requirements.txt` files to the module. ```hcl module "agent_engine" { - source = "./fabric/modules/agent-engine" - name = "my-agent" - project_id = var.project_id - region = var.region - generate_pickle = false + source = "./fabric/modules/agent-engine" + name = "my-agent" + project_id = var.project_id + region = var.region agent_engine_config = { agent_framework = "google-adk" } - source_files = { - path = "assets/src/" + deployment_files = { + package_config = { + dependencies_path = "assets/src/dependencies.tar.gz" + pickle_path = "assets/src/pickle.pkl" + requirements_path = "assets/src/requirements.txt" + } + source_config = null } } # tftest inventory=minimal-pickle.yaml ``` +### Unmanaged deployments + +By default, this module tracks and controls code updates. This means you can only the agent code via Terraform. +Anyway, you may want to delegate this operation to third-party tools, outside Terraform. +To do so, deploy the first revision of your code by using the module (this can even be a hello world) and set `var.managed` to `false`. + +```hcl +module "agent_engine" { + source = "./fabric/modules/agent-engine" + name = "my-agent" + project_id = var.project_id + region = var.region + managed = false + + agent_engine_config = { + agent_framework = "google-adk" + } + + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } + } +} +# tftest inventory=unmanaged.yaml +``` + ## Service accounts By default, the module creates a dedicated service account for your agent and grants it the roles needed to deploy the agent. The default roles are defined in `var.service_account_config.roles`. You can add more roles, as needed. @@ -131,8 +164,10 @@ module "agent_engine" { create = false } - source_files = { - path = "assets/src/" + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } } } # tftest inventory=sa-default.yaml @@ -156,8 +191,10 @@ module "agent_engine" { email = "my-sa@${var.project_id}.iam.gserviceaccount.com" } - source_files = { - path = "assets/src/" + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } } } # tftest inventory=sa-custom.yaml @@ -181,8 +218,10 @@ module "agent_engine" { agent_framework = "google-adk" } - source_files = { - path = "assets/src/" + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } } } # tftest inventory=encryption.yaml @@ -212,8 +251,10 @@ module "agent_engine" { } } - source_files = { - path = "assets/src/" + deployment_files = { + source_config = { + source_path = "assets/src/source.tar.gz" + } } } # tftest inventory=environment.yaml @@ -227,22 +268,23 @@ The module allows you to dynamically reference context values for resources crea | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [agent_engine_config](variables.tf#L17) | The agent configuration. | object({…}) | ✓ | | -| [name](variables.tf#L77) | The name of the agent. | string | ✓ | | -| [project_id](variables.tf#L83) | The id of the project where to deploy the agent. | string | ✓ | | -| [region](variables.tf#L89) | The region where to deploy the agent. | string | ✓ | | -| [bucket_config](variables.tf#L32) | The GCS bucket configuration. | object({…}) | | {} | -| [context](variables.tf#L44) | Context-specific interpolations. | object({…}) | | {} | -| [description](variables.tf#L57) | The Agent Engine description. | string | | "Terraform managed." | -| [encryption_key](variables.tf#L64) | The full resource name of the Cloud KMS CryptoKey. | string | | null | -| [generate_pickle](variables.tf#L70) | Generate the pickle file from a source file. | bool | | true | +| [agent_engine_config](variables.tf#L17) | The agent configuration. | object({…}) | ✓ | | +| [name](variables.tf#L121) | The name of the agent. | string | ✓ | | +| [project_id](variables.tf#L127) | The id of the project where to deploy the agent. | string | ✓ | | +| [region](variables.tf#L133) | The region where to deploy the agent. | string | ✓ | | +| [bucket_config](variables.tf#L40) | The GCS bucket configuration. | object({…}) | | {} | +| [context](variables.tf#L52) | Context-specific interpolations. | object({…}) | | {} | +| [deployment_files](variables.tf#L65) | The to source files path and names. | object({…}) | | {…} | +| [description](variables.tf#L101) | The Agent Engine description. | string | | "Terraform managed." | +| [encryption_key](variables.tf#L108) | The full resource name of the Cloud KMS CryptoKey. | string | | null | +| [managed](variables.tf#L114) | Whether the Terraform module should control the code updates. | bool | | true | | [service_account_config](variables-serviceaccount.tf#L18) | Service account configurations. | object({…}) | | {} | -| [source_files](variables.tf#L95) | The to source files path and names. | object({…}) | | {} | ## Outputs | name | description | sensitive | |---|---|:---:| -| [id](outputs.tf#L17) | Fully qualified Agent Engine id. | | -| [service_account](outputs.tf#L22) | Service account resource. | | +| [agent](outputs.tf#L17) | The Agent Engine object. | | +| [id](outputs.tf#L22) | Fully qualified Agent Engine id. | | +| [service_account](outputs.tf#L27) | Service account resource. | | diff --git a/modules/agent-engine/agent-managed.tf b/modules/agent-engine/agent-managed.tf new file mode 100644 index 000000000..5c1a10948 --- /dev/null +++ b/modules/agent-engine/agent-managed.tf @@ -0,0 +1,115 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +resource "google_vertex_ai_reasoning_engine" "managed" { + count = var.managed ? 1 : 0 + display_name = var.name + project = local.project_id + description = var.description + region = local.location + + dynamic "encryption_spec" { + for_each = var.encryption_key == null ? {} : { 1 = 1 } + + content { + kms_key_name = lookup( + local.ctx.kms_keys, + var.encryption_key, + var.encryption_key + ) + } + } + + spec { + agent_framework = var.agent_engine_config.agent_framework + class_methods = ( + length(var.agent_engine_config.class_methods) > 0 + ? jsonencode(var.agent_engine_config.class_methods) + : null + ) + service_account = local.service_account_email + + dynamic "deployment_spec" { + for_each = ( + var.agent_engine_config.container_concurrency != null || + var.agent_engine_config.max_instances != null || + var.agent_engine_config.min_instances != null || + var.agent_engine_config.resource_limits != null || + length(var.agent_engine_config.environment_variables) > 0 || + length(var.agent_engine_config.secret_environment_variables) > 0 + ? { 1 = 1 } + : {} + ) + + content { + container_concurrency = var.agent_engine_config.container_concurrency + max_instances = var.agent_engine_config.max_instances + min_instances = var.agent_engine_config.min_instances + resource_limits = var.agent_engine_config.resource_limits + + dynamic "env" { + for_each = var.agent_engine_config.environment_variables + + content { + name = env.key + value = env.value + } + } + + dynamic "secret_env" { + for_each = var.agent_engine_config.secret_environment_variables + + content { + name = secret_env.key + + secret_ref { + secret = secret_env.value.secret_id + version = secret_env.value.version + } + } + } + } + } + + dynamic "package_spec" { + for_each = var.deployment_files.package_config != null ? { 1 = 1 } : {} + + content { + python_version = var.agent_engine_config.python_version + dependency_files_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}" + requirements_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}" + pickle_object_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}" + } + } + + dynamic "source_code_spec" { + for_each = var.deployment_files.source_config != null ? { 1 = 1 } : {} + + content { + inline_source { + source_archive = filebase64(var.deployment_files.source_config.source_path) + } + + python_spec { + entrypoint_module = var.deployment_files.source_config.entrypoint_module + entrypoint_object = var.deployment_files.source_config.entrypoint_object + requirements_file = var.deployment_files.source_config.requirements_path + version = var.agent_engine_config.python_version + } + } + } + } +} diff --git a/modules/agent-engine/agent-unmanaged.tf b/modules/agent-engine/agent-unmanaged.tf new file mode 100644 index 000000000..9c7b5260d --- /dev/null +++ b/modules/agent-engine/agent-unmanaged.tf @@ -0,0 +1,122 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +resource "google_vertex_ai_reasoning_engine" "unmanaged" { + count = var.managed ? 0 : 1 + display_name = var.name + project = local.project_id + description = var.description + region = local.location + + dynamic "encryption_spec" { + for_each = var.encryption_key == null ? {} : { 1 = 1 } + + content { + kms_key_name = lookup( + local.ctx.kms_keys, + var.encryption_key, + var.encryption_key + ) + } + } + + spec { + agent_framework = var.agent_engine_config.agent_framework + class_methods = ( + length(var.agent_engine_config.class_methods) > 0 + ? jsonencode(var.agent_engine_config.class_methods) + : null + ) + service_account = local.service_account_email + + dynamic "deployment_spec" { + for_each = ( + var.agent_engine_config.container_concurrency != null || + var.agent_engine_config.max_instances != null || + var.agent_engine_config.min_instances != null || + var.agent_engine_config.resource_limits != null || + length(var.agent_engine_config.environment_variables) > 0 || + length(var.agent_engine_config.secret_environment_variables) > 0 + ? { 1 = 1 } + : {} + ) + + content { + container_concurrency = var.agent_engine_config.container_concurrency + max_instances = var.agent_engine_config.max_instances + min_instances = var.agent_engine_config.min_instances + resource_limits = var.agent_engine_config.resource_limits + + dynamic "env" { + for_each = var.agent_engine_config.environment_variables + + content { + name = env.key + value = env.value + } + } + + dynamic "secret_env" { + for_each = var.agent_engine_config.secret_environment_variables + + content { + name = secret_env.key + + secret_ref { + secret = secret_env.value.secret_id + version = secret_env.value.version + } + } + } + } + } + + dynamic "package_spec" { + for_each = var.deployment_files.package_config == null ? {} : { 1 = 1 } + + content { + python_version = var.agent_engine_config.python_version + dependency_files_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}" + requirements_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}" + pickle_object_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}" + } + } + + dynamic "source_code_spec" { + for_each = var.deployment_files.source_config == null ? {} : { 1 = 1 } + + content { + inline_source { + source_archive = filebase64(var.deployment_files.source_config.source_path) + } + + python_spec { + entrypoint_module = var.deployment_files.source_config.entrypoint_module + entrypoint_object = var.deployment_files.source_config.entrypoint_object + requirements_file = var.deployment_files.source_config.requirements_path + version = var.agent_engine_config.python_version + } + } + } + } + + lifecycle { + ignore_changes = [ + spec[0].package_spec, + spec[0].source_code_spec[0].inline_source[0].source_archive + ] + } +} diff --git a/modules/agent-engine/main.tf b/modules/agent-engine/main.tf index a50c42c27..a700778c8 100644 --- a/modules/agent-engine/main.tf +++ b/modules/agent-engine/main.tf @@ -16,8 +16,13 @@ locals { _ctx_p = "$" + _resource = ( + var.managed + ? try(google_vertex_ai_reasoning_engine.managed[0], null) + : try(google_vertex_ai_reasoning_engine.unmanaged[0], null) + ) bucket_name = ( - var.bucket_config.create + var.deployment_files.package_config != null && var.bucket_config.create ? google_storage_bucket.default[0].name : coalesce(var.bucket_config.name, var.name) ) @@ -32,79 +37,9 @@ locals { project_id = lookup( local.ctx.project_ids, var.project_id, var.project_id ) -} - -resource "google_vertex_ai_reasoning_engine" "default" { - display_name = var.name - project = local.project_id - description = var.description - region = local.location - - dynamic "encryption_spec" { - for_each = var.encryption_key == null ? {} : { 1 = 1 } - - content { - kms_key_name = lookup( - local.ctx.kms_keys, - var.encryption_key, - var.encryption_key - ) - } - } - - spec { - agent_framework = var.agent_engine_config.agent_framework - class_methods = ( - length(var.agent_engine_config.class_methods) > 0 - ? jsonencode(var.agent_engine_config.class_methods) - : null - ) - service_account = local.service_account_email - - dynamic "deployment_spec" { - for_each = ( - # length(var.container_spec) > 0 || - length(var.agent_engine_config.environment_variables) > 0 || - length(var.agent_engine_config.secret_environment_variables) > 0 - ? { 1 = 1 } - : {} - ) - - content { - dynamic "env" { - for_each = var.agent_engine_config.environment_variables - - content { - name = env.key - value = env.value - } - } - - dynamic "secret_env" { - for_each = var.agent_engine_config.secret_environment_variables - - content { - name = secret_env.key - - secret_ref { - secret = secret_env.value.secret_id - version = secret_env.value.version - } - } - } - } - } - - package_spec { - python_version = var.agent_engine_config.python_version - dependency_files_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies.name}" - requirements_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.requirements.name}" - pickle_object_gcs_uri = ( - var.generate_pickle - ? "gs://${local.bucket_name}/${google_storage_bucket_object.pickle_from_src[0].name}" - : "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}" - ) - } + resource = { + id = local._resource.id + object = local._resource } } @@ -119,7 +54,11 @@ resource "time_sleep" "wait_5_minutes" { } resource "google_storage_bucket" "default" { - count = var.bucket_config.create ? 1 : 0 + count = ( + var.bucket_config.create + && var.deployment_files.package_config != null + ? 1 : 0 + ) name = coalesce(var.bucket_config.name, var.name) project = local.project_id location = local.location @@ -127,50 +66,32 @@ resource "google_storage_bucket" "default" { force_destroy = !var.bucket_config.deletion_protection } -resource "null_resource" "default" { - count = var.generate_pickle ? 1 : 0 - - provisioner "local-exec" { - command = join(" ", [ - "python", - "./tools/serialize_agent.py", - "${var.source_files.path}/${var.source_files.pickle_src}", - "--output-file ${var.source_files.path}/${var.source_files.pickle_out}", - "--variable-name ${var.source_files.pickle_src_var_name}" - ]) - } -} - resource "google_storage_bucket_object" "dependencies" { - name = "dependencies.tar.gz" - bucket = local.bucket_name - source = "${var.source_files.path}/${var.source_files.dependencies}" - source_md5hash = filemd5("${var.source_files.path}/${var.source_files.dependencies}") -} - -resource "google_storage_bucket_object" "pickle_from_src" { - count = var.generate_pickle ? 1 : 0 - name = "pickle.pkl" - bucket = local.bucket_name - source = "${var.source_files.path}/${var.source_files.pickle_out}" - source_md5hash = filemd5("${var.source_files.path}/${var.source_files.pickle_out}") - - depends_on = [ - null_resource.default - ] + count = var.deployment_files.package_config != null ? 1 : 0 + name = "dependencies.tar.gz" + bucket = local.bucket_name + source = try(var.deployment_files.package_config.dependencies_path, null) + source_md5hash = filemd5( + try(var.deployment_files.package_config.dependencies_path, null) + ) } resource "google_storage_bucket_object" "pickle" { - count = var.generate_pickle ? 0 : 1 - name = "pickle.pkl" - bucket = local.bucket_name - source = "${var.source_files.path}/${var.source_files.pickle_out}" - source_md5hash = filemd5("${var.source_files.path}/${var.source_files.pickle_out}") + count = var.deployment_files.package_config != null ? 1 : 0 + name = "pickle.pkl" + bucket = local.bucket_name + source = try(var.deployment_files.package_config.pickle_path, null) + source_md5hash = filemd5( + try(var.deployment_files.package_config.pickle_path) + ) } resource "google_storage_bucket_object" "requirements" { - name = "requirements.txt" - bucket = local.bucket_name - source = "${var.source_files.path}/${var.source_files.requirements}" - source_md5hash = filemd5("${var.source_files.path}/${var.source_files.requirements}") + count = var.deployment_files.package_config != null ? 1 : 0 + name = "requirements.txt" + bucket = local.bucket_name + source = try(var.deployment_files.package_config.requirements_path, null) + source_md5hash = filemd5( + try(var.deployment_files.package_config.requirements_path) + ) } diff --git a/modules/agent-engine/outputs.tf b/modules/agent-engine/outputs.tf index 0b418d1c1..8eaa48647 100644 --- a/modules/agent-engine/outputs.tf +++ b/modules/agent-engine/outputs.tf @@ -14,9 +14,14 @@ * limitations under the License. */ +output "agent" { + description = "The Agent Engine object." + value = local.resource.object +} + output "id" { description = "Fully qualified Agent Engine id." - value = google_vertex_ai_reasoning_engine.default.id + value = local.resource.id } output "service_account" { diff --git a/modules/agent-engine/tools/requirements.txt b/modules/agent-engine/tools/requirements.txt deleted file mode 100644 index 37d5682cf..000000000 --- a/modules/agent-engine/tools/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -cloudpickle diff --git a/modules/agent-engine/tools/serialize_agent.py b/modules/agent-engine/tools/serialize_agent.py deleted file mode 100644 index 9b5619303..000000000 --- a/modules/agent-engine/tools/serialize_agent.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import argparse -import cloudpickle -import importlib.util -import os -import sys -from google.adk.agents import LlmAgent - - -def serialize_agent_from_file(input_file, variable_name, output_file): - """ - Dynamically loads a Python module from a full file path, accesses a - top-level variable containing an agent object, and serializes that object - to a specified output file. - - Args: - input_file (str): The full path to the Python source file. - variable_name (str): The name of the variable holding the agent object. - output_file (str): The full path for the output pickle file. - """ - try: - output_dir = os.path.dirname(output_file) - if output_dir and not os.path.isdir(output_dir): - print(f"Error: The output directory '{output_dir}' does not exist.", - file=sys.stderr) - return - - module_name = os.path.splitext(os.path.basename(input_file))[0] - - spec = importlib.util.spec_from_file_location(module_name, input_file) - if spec is None or spec.loader is None: - print(f"Error: Could not import module from {input_file}", - file=sys.stderr) - return - - module = importlib.util.module_from_spec(spec) - - spec.loader.exec_module(module) - - local_agent = getattr(module, variable_name) - - with open(output_file, "wb") as f: - cloudpickle.dump(local_agent, f) - - print( - f"Successfully serialized '{variable_name}' from '{input_file}' to '{output_file}'" - ) - - except FileNotFoundError: - print(f"Error: The input file '{input_file}' was not found.", - file=sys.stderr) - except AttributeError: - print( - f"Error: The variable '{variable_name}' was not found in '{input_file}'.", - file=sys.stderr) - except Exception as e: - print(f"An unexpected error occurred: {e}", file=sys.stderr) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description= - "Serialize a dynamically loaded agent from a variable in a specified file." - ) - parser.add_argument( - "input_file", - help="The full path to the Python source file (e.g., 'my_agents/main.py')." - ) - parser.add_argument( - "--variable-name", default="local_agent", help= - "The name of the agent variable to serialize (default: 'local_agent').") - parser.add_argument( - "--output-file", default="pickle.pkl", help= - "The full path for the output pickle file (e.g., 'output/agent.pkl'). Default is 'pickle.pkl' in the current directory." - ) - - args = parser.parse_args() - - serialize_agent_from_file(args.input_file, args.variable_name, - args.output_file) diff --git a/modules/agent-engine/variables-serviceaccount.tf b/modules/agent-engine/variables-serviceaccount.tf index 5f4166c69..8d599bb1c 100644 --- a/modules/agent-engine/variables-serviceaccount.tf +++ b/modules/agent-engine/variables-serviceaccount.tf @@ -1,5 +1,5 @@ /** - * Copyright 2024 Google LLC + * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/modules/agent-engine/variables.tf b/modules/agent-engine/variables.tf index c40ae635c..cf96bb908 100644 --- a/modules/agent-engine/variables.tf +++ b/modules/agent-engine/variables.tf @@ -20,13 +20,21 @@ variable "agent_engine_config" { # Add validation once API stabilizes agent_framework = string class_methods = optional(list(any), []) + container_concurrency = optional(number) environment_variables = optional(map(string), {}) + max_instances = optional(number) + min_instances = optional(number) python_version = optional(string, "3.12") + resource_limits = optional(object({ + cpu = string + memory = string + })) secret_environment_variables = optional(map(object({ secret_id = string version = optional(string, "latest") })), {}) }) + nullable = false } variable "bucket_config" { @@ -54,6 +62,42 @@ variable "context" { default = {} } +variable "deployment_files" { + description = "The to source files path and names." + type = object({ + package_config = optional(object({ + dependencies_path = optional(string, "./src/dependencies.tar.gz") + pickle_path = optional(string, "./src/pickle.pkl") + requirements_path = optional(string, "./src/requirements.txt") + }), null) + source_config = optional(object({ + entrypoint_module = optional(string, "agent") + entrypoint_object = optional(string, "agent") + requirements_path = optional(string, "requirements.txt") + source_path = optional(string, "./src/source.tar.gz") + }), null) + }) + nullable = false + default = { + package_config = null + source_config = {} + } + validation { + condition = ( + var.deployment_files.package_config != null || + var.deployment_files.source_config != null + ) + error_message = "You must provide either 'package_config' or 'source_config'." + } + validation { + condition = !( + var.deployment_files.package_config != null && + var.deployment_files.source_config != null + ) + error_message = "You cannot specify both 'package_config' and 'source_config' simultaneously." + } +} + variable "description" { description = "The Agent Engine description." type = string @@ -67,8 +111,8 @@ variable "encryption_key" { default = null } -variable "generate_pickle" { - description = "Generate the pickle file from a source file." +variable "managed" { + description = "Whether the Terraform module should control the code updates." type = bool nullable = false default = true @@ -91,17 +135,3 @@ variable "region" { type = string nullable = false } - -variable "source_files" { - description = "The to source files path and names." - type = object({ - dependencies = optional(string, "dependencies.tar.gz") - path = optional(string, "./src") - pickle_out = optional(string, "pickle.pkl") - pickle_src = optional(string, "agent.py") - pickle_src_var_name = optional(string, "local_agent") - requirements = optional(string, "requirements.txt") - }) - nullable = false - default = {} -} diff --git a/modules/alloydb/README.md b/modules/alloydb/README.md index 8f7679867..35f2390ac 100644 --- a/modules/alloydb/README.md +++ b/modules/alloydb/README.md @@ -343,37 +343,37 @@ module "alloydb" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [cluster_name](variables.tf#L81) | Name of the primary cluster. | string | ✓ | | -| [instance_name](variables.tf#L208) | Name of primary instance. | string | ✓ | | -| [location](variables.tf#L220) | Region or zone of the cluster and instance. | string | ✓ | | -| [network_config](variables.tf#L265) | Network configuration for cluster and instance. Only one between psa_config and psc_config can be used. | object({…}) | ✓ | | -| [project_id](variables.tf#L300) | The ID of the project where this instances will be created. | string | ✓ | | +| [cluster_name](variables.tf#L84) | Name of the primary cluster. | string | ✓ | | +| [instance_name](variables.tf#L211) | Name of primary instance. | string | ✓ | | +| [location](variables.tf#L223) | Region or zone of the cluster and instance. | string | ✓ | | +| [network_config](variables.tf#L268) | Network configuration for cluster and instance. Only one between psa_config and psc_config can be used. | object({…}) | ✓ | | +| [project_id](variables.tf#L303) | The ID of the project where this instances will be created. | string | ✓ | | | [annotations](variables.tf#L17) | Map FLAG_NAME=>VALUE for annotations which allow client tools to store small amount of arbitrary data. | map(string) | | null | -| [automated_backup_configuration](variables.tf#L23) | Automated backup settings for cluster. | object({…}) | | {} | -| [availability_type](variables.tf#L58) | Availability type for the primary replica. Either `ZONAL` or `REGIONAL`. | string | | "REGIONAL" | -| [client_connection_config](variables.tf#L64) | Client connection config. | object({…}) | | null | -| [cluster_display_name](variables.tf#L75) | Display name of the primary cluster. | string | | null | -| [continuous_backup_configuration](variables.tf#L87) | Continuous backup settings for cluster. | object({…}) | | {} | -| [cross_region_replication](variables.tf#L97) | Cross region replication config. | object({…}) | | {} | -| [database_version](variables.tf#L154) | Database type and version to create. | string | | "POSTGRES_15" | -| [deletion_policy](variables.tf#L160) | AlloyDB cluster and instance deletion policy. | string | | null | -| [deletion_protection](variables.tf#L166) | Whether Terraform will be prevented from destroying the cluster. When the field is set to true or unset in Terraform state, a terraform apply or terraform destroy that would delete the cluster will fail. When the field is set to false, deleting the cluster is allowed. | bool | | null | -| [display_name](variables.tf#L172) | AlloyDB instance display name. | string | | null | -| [encryption_config](variables.tf#L178) | Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'. | object({…}) | | null | -| [flags](variables.tf#L187) | Map FLAG_NAME=>VALUE for database-specific tuning. | map(string) | | null | -| [gce_zone](variables.tf#L193) | The GCE zone that the instance should serve from. This can ONLY be specified for ZONAL instances. If present for a REGIONAL instance, an error will be thrown. | string | | null | -| [initial_user](variables.tf#L199) | AlloyDB cluster initial user credentials. | object({…}) | | null | -| [labels](variables.tf#L214) | Labels to be attached to all instances. | map(string) | | null | -| [machine_config](variables.tf#L226) | AlloyDB machine config. | object({…}) | | {} | -| [maintenance_config](variables.tf#L240) | Set maintenance window configuration. | object({…}) | | {} | -| [prefix](variables.tf#L290) | Optional prefix used to generate instance names. | string | | null | -| [project_number](variables.tf#L305) | The project number of the project where this instances will be created. Only used for testing purposes. | string | | null | -| [query_insights_config](variables.tf#L311) | Query insights config. | object({…}) | | {} | -| [read_pool](variables.tf#L322) | Map of read pool instances to create in the primary cluster. | map(object({…})) | | {} | -| [skip_await_major_version_upgrade](variables.tf#L367) | Set to true to skip awaiting on the major version upgrade of the cluster. | bool | | true | -| [subscription_type](variables.tf#L373) | The subscription type of cluster. Possible values are: 'STANDARD' or 'TRIAL'. | string | | "STANDARD" | -| [tag_bindings](variables.tf#L379) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} | -| [users](variables.tf#L386) | Map of users to create in the primary instance (and replicated to other replicas). Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'ALLOYDB_BUILT_IN' or 'ALLOYDB_IAM_USER'. | map(object({…})) | | {} | +| [automated_backup_configuration](variables.tf#L23) | Automated backup settings for cluster. | object({…}) | | {} | +| [availability_type](variables.tf#L61) | Availability type for the primary replica. Either `ZONAL` or `REGIONAL`. | string | | "REGIONAL" | +| [client_connection_config](variables.tf#L67) | Client connection config. | object({…}) | | null | +| [cluster_display_name](variables.tf#L78) | Display name of the primary cluster. | string | | null | +| [continuous_backup_configuration](variables.tf#L90) | Continuous backup settings for cluster. | object({…}) | | {} | +| [cross_region_replication](variables.tf#L100) | Cross region replication config. | object({…}) | | {} | +| [database_version](variables.tf#L157) | Database type and version to create. | string | | "POSTGRES_15" | +| [deletion_policy](variables.tf#L163) | AlloyDB cluster and instance deletion policy. | string | | null | +| [deletion_protection](variables.tf#L169) | Whether Terraform will be prevented from destroying the cluster. When the field is set to true or unset in Terraform state, a terraform apply or terraform destroy that would delete the cluster will fail. When the field is set to false, deleting the cluster is allowed. | bool | | null | +| [display_name](variables.tf#L175) | AlloyDB instance display name. | string | | null | +| [encryption_config](variables.tf#L181) | Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'. | object({…}) | | null | +| [flags](variables.tf#L190) | Map FLAG_NAME=>VALUE for database-specific tuning. | map(string) | | null | +| [gce_zone](variables.tf#L196) | The GCE zone that the instance should serve from. This can ONLY be specified for ZONAL instances. If present for a REGIONAL instance, an error will be thrown. | string | | null | +| [initial_user](variables.tf#L202) | AlloyDB cluster initial user credentials. | object({…}) | | null | +| [labels](variables.tf#L217) | Labels to be attached to all instances. | map(string) | | null | +| [machine_config](variables.tf#L229) | AlloyDB machine config. | object({…}) | | {} | +| [maintenance_config](variables.tf#L243) | Set maintenance window configuration. | object({…}) | | {} | +| [prefix](variables.tf#L293) | Optional prefix used to generate instance names. | string | | null | +| [project_number](variables.tf#L308) | The project number of the project where this instances will be created. Only used for testing purposes. | string | | null | +| [query_insights_config](variables.tf#L314) | Query insights config. | object({…}) | | {} | +| [read_pool](variables.tf#L325) | Map of read pool instances to create in the primary cluster. | map(object({…})) | | {} | +| [skip_await_major_version_upgrade](variables.tf#L370) | Set to true to skip awaiting on the major version upgrade of the cluster. | bool | | true | +| [subscription_type](variables.tf#L376) | The subscription type of cluster. Possible values are: 'STANDARD' or 'TRIAL'. | string | | "STANDARD" | +| [tag_bindings](variables.tf#L382) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} | +| [users](variables.tf#L389) | Map of users to create in the primary instance (and replicated to other replicas). Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'ALLOYDB_BUILT_IN' or 'ALLOYDB_IAM_USER'. | map(object({…})) | | {} | ## Outputs diff --git a/modules/alloydb/main.tf b/modules/alloydb/main.tf index 4b623e261..6569c4e81 100644 --- a/modules/alloydb/main.tf +++ b/modules/alloydb/main.tf @@ -102,11 +102,14 @@ resource "google_alloydb_cluster" "primary" { weekly_schedule { days_of_week = var.automated_backup_configuration.weekly_schedule.days_of_week - start_times { - hours = var.automated_backup_configuration.weekly_schedule.start_times.hours - minutes = 0 - seconds = 0 - nanos = 0 + dynamic "start_times" { + for_each = var.automated_backup_configuration.weekly_schedule.start_times + content { + hours = start_times.value.hours + minutes = 0 + seconds = 0 + nanos = 0 + } } } diff --git a/modules/alloydb/variables.tf b/modules/alloydb/variables.tf index 9df621486..c9314a9ca 100644 --- a/modules/alloydb/variables.tf +++ b/modules/alloydb/variables.tf @@ -30,9 +30,9 @@ variable "automated_backup_configuration" { days_of_week = optional(list(string), [ "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY" ]) - start_times = optional(object({ - hours = optional(number, 23) - }), {}) + start_times = optional(list(object({ + hours = number + })), [{ hours = 23 }]) }), {}) retention_count = optional(number, 7) retention_period = optional(string) @@ -45,8 +45,11 @@ variable "automated_backup_configuration" { # Backup window validation below !(var.automated_backup_configuration.retention_count != null && var.automated_backup_configuration.retention_period != null) && # Backup window hours below - var.automated_backup_configuration.weekly_schedule.start_times.hours >= 0 && - var.automated_backup_configuration.weekly_schedule.start_times.hours <= 23 && + (alltrue([ + for v in var.automated_backup_configuration.weekly_schedule.start_times : + v.hours >= 0 && + v.hours <= 23 + ])) && # Backup window day validation setintersection(["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"], var.automated_backup_configuration.weekly_schedule.days_of_week) == toset(var.automated_backup_configuration.weekly_schedule.days_of_week) ) : true diff --git a/modules/api-gateway/recipe-multi-region/function/package-lock.json b/modules/api-gateway/recipe-multi-region/function/package-lock.json index 2ba82adee..e41cc95c7 100644 --- a/modules/api-gateway/recipe-multi-region/function/package-lock.json +++ b/modules/api-gateway/recipe-multi-region/function/package-lock.json @@ -12,7 +12,7 @@ "@google-cloud/functions-framework": "^4.0.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" } }, "node_modules/@babel/code-frame": { @@ -37,14 +37,15 @@ } }, "node_modules/@google-cloud/functions-framework": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/functions-framework/-/functions-framework-4.0.0.tgz", - "integrity": "sha512-CNcYrz0/hw35Oq0D9RipHUB8KzH4ixq7o12L//qoOg0TFYv4953KrzCo0L2VP++19P39RShKTftDKMFmQhCeEw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/functions-framework/-/functions-framework-4.0.1.tgz", + "integrity": "sha512-/ui6HI2yNVPNQXGCR+3FMMUEXqm1vMt+xh7oS+rqpVeDjjAYmFYyER1SDYlwvhau/hE53vSUyaDbicb/ilFzJA==", + "license": "Apache-2.0", "dependencies": { - "@types/express": "^4.17.21", - "body-parser": "1.20.3", - "cloudevents": "^8.0.2", - "express": "^4.21.2", + "@types/express": "^5.0.0", + "body-parser": "2.2.0", + "cloudevents": "^10.0.0", + "express": "^5.0.0", "minimist": "^1.2.8", "on-finished": "^2.3.0", "read-package-up": "^11.0.0", @@ -59,9 +60,10 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -71,25 +73,27 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/express": { - "version": "4.17.22", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.22.tgz", - "integrity": "sha512-eZUmSnhRX9YRSkplpz0N+k6NljUUn5l3EWZIKZvYzhvMphEuNiyyy1viH/ejgt66JWgALwC/gtSUAeQKtSwW/w==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz", + "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -98,21 +102,18 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", - "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/normalize-package-data": { @@ -123,39 +124,42 @@ "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==" + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "license": "MIT", "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "@types/node": "*" } }, "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" @@ -165,6 +169,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -180,6 +185,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -192,15 +198,11 @@ } } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -212,40 +214,39 @@ } }, "node_modules/bignumber.js": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", - "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=18" } }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -254,6 +255,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", @@ -271,6 +273,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -283,6 +286,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -295,9 +299,10 @@ } }, "node_modules/cloudevents": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/cloudevents/-/cloudevents-8.0.3.tgz", - "integrity": "sha512-wTixKNjfLeyj9HQpESvLVVO4xgdqdvX4dTeg1IZ2SCunu/fxVzCamcIZneEyj31V82YolFCKwVeSkr8zResB0Q==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cloudevents/-/cloudevents-10.0.0.tgz", + "integrity": "sha512-uyzC+PpMMRawbouHO+3mlisr3QfEDObmo2pN4oTTF6dZncZgpIzdasZx0tRBFI1dMsqCLZZXMtz8cUuvYqHdbw==", + "license": "Apache-2.0", "dependencies": { "ajv": "^8.11.0", "ajv-formats": "^2.1.1", @@ -307,53 +312,71 @@ "uuid": "^8.3.2" }, "engines": { - "node": ">=16 <=22" + "node": ">=20 <=24" } }, "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -370,23 +393,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -399,12 +415,14 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -413,6 +431,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -421,6 +440,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -429,6 +449,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -439,55 +460,95 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", + "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" }, "funding": { "type": "opencollective", @@ -497,12 +558,13 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -512,23 +574,28 @@ "type": "opencollective", "url": "https://opencollective.com/fastify" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/find-up-simple": { @@ -546,6 +613,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", "dependencies": { "is-callable": "^1.2.7" }, @@ -560,30 +628,43 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -607,6 +688,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -619,6 +701,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -630,6 +713,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -641,6 +725,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -652,6 +737,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -666,6 +752,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -685,26 +772,32 @@ } }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" @@ -724,12 +817,14 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -738,6 +833,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -753,6 +849,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -761,12 +858,14 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -777,10 +876,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", @@ -798,6 +904,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" }, @@ -817,6 +924,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -824,7 +932,8 @@ "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/lru-cache": { "version": "10.4.3", @@ -835,62 +944,55 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/minimist": { @@ -902,14 +1004,16 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -931,6 +1035,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -942,6 +1047,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -949,6 +1055,15 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/parse-json": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", @@ -969,14 +1084,20 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/picocolors": { "version": "1.1.1", @@ -987,6 +1108,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -995,6 +1117,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -1003,6 +1126,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -1012,11 +1136,12 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -1029,22 +1154,40 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/read-package-up": { @@ -1085,33 +1228,32 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -1127,7 +1269,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/semver": { "version": "7.7.2", @@ -1141,59 +1284,55 @@ } }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -1209,12 +1348,14 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -1233,6 +1374,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -1248,6 +1390,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -1265,6 +1408,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -1308,9 +1452,10 @@ "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==" }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1319,6 +1464,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } @@ -1335,21 +1481,24 @@ } }, "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -1366,6 +1515,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1374,6 +1524,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -1382,18 +1533,11 @@ "which-typed-array": "^1.1.2" } }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -1411,6 +1555,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1419,6 +1564,7 @@ "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -1434,6 +1580,12 @@ "funding": { "url": "https://github.com/sponsors/ljharb" } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" } } } diff --git a/modules/compute-vm/variables.tf b/modules/compute-vm/variables.tf index 113df157a..01177dba8 100644 --- a/modules/compute-vm/variables.tf +++ b/modules/compute-vm/variables.tf @@ -83,9 +83,9 @@ variable "attached_disks" { } validation { condition = alltrue([for d in var.attached_disks : - (d.options.architecture == null || contains(["ARM64", "x86_64"], d.options.architecture)) + (d.options.architecture == null || contains(["ARM64", "X86_64"], d.options.architecture)) ]) - error_message = "Architecture can be null, 'x86_64' or 'ARM64'." + error_message = "Architecture can be null, 'X86_64' or 'ARM64'." } } @@ -125,9 +125,9 @@ variable "boot_disk" { validation { condition = ( var.boot_disk.initialize_params.architecture == null || - contains(["ARM64", "x86_64"], var.boot_disk.initialize_params.architecture) + contains(["ARM64", "X86_64"], var.boot_disk.initialize_params.architecture) ) - error_message = "Architecture can be null, 'x86_64' or 'ARM64'." + error_message = "Architecture can be null, 'X86_64' or 'ARM64'." } } diff --git a/modules/net-lb-app-int-cross-region/README.md b/modules/net-lb-app-int-cross-region/README.md index a1e4a8766..f12fb801b 100644 --- a/modules/net-lb-app-int-cross-region/README.md +++ b/modules/net-lb-app-int-cross-region/README.md @@ -18,6 +18,7 @@ Due to the complexity of the underlying resources, changes to the configuration - [Serverless NEG creation](#serverless-neg-creation) - [Private Service Connect NEG creation](#private-service-connect-neg-creation) - [URL Map](#url-map) + - [PSC service attachment](#psc-service-attachment) - [Complex example](#complex-example) - [Deploying changes to load balancer configurations](#deploying-changes-to-load-balancer-configurations) - [Recipes](#recipes) @@ -424,7 +425,9 @@ module "ilb-l7" { backend_service_configs = { default = { backends = [{ - group = "neg" + group = "neg-ew1" + }, { + group = "neg-ew4" }] health_checks = [] } @@ -556,6 +559,71 @@ module "ilb-l7" { # tftest modules=1 resources=7 ``` +### PSC service attachment +The optional `service_attachment` variable allows [publishing Private Service Connect service](https://cloud.google.com/vpc/docs/configure-private-service-connect-producer) by configuring service attachment for all forwarding rules in every configured region. + +```hcl +module "ilb-l7" { + source = "./fabric/modules/net-lb-app-int-cross-region" + name = "ilb-test" + project_id = var.project_id + backend_service_configs = { + default = { + backends = [{ + group = "neg-ew1" + }, { + group = "neg-ew4" + }] + health_checks = [] + } + } + health_check_configs = {} + neg_configs = { + neg-ew1 = { + cloudrun = { + region = "europe-west1" + target_service = { + name = "my-run-service-ew1" + } + } + } + neg-ew4 = { + cloudrun = { + region = "europe-west4" + target_service = { + name = "my-run-service-ew4" + } + } + } + } + vpc_config = { + network = var.vpc.self_link + subnetworks = { + europe-west1 = var.subnet1.self_link + europe-west4 = var.subnet2.self_link + } + } + + service_attachment = { + nat_subnets = { + europe-west1 = [var.subnet_psc_1.self_link] + europe-west4 = [var.subnet_psc_2.self_link] + } + reconcile_connections = false + consumer_accept_lists = { + # map of `project_id` => `connection_limit` + (var.project_id) = 10 + } + domain_name = { + europe-west1 = "ew1.p.example.com." + europe-west4 = "ew4.p.example.com." + } + } +} +# tftest modules=1 resources=9 +``` + + ### Complex example This example mixes group and NEG backends, and shows how to set HTTPS for specific backends. @@ -738,7 +806,7 @@ When deploying changes to load balancer configuration please refer to [net-lb-ap | [backend-service.tf](./backend-service.tf) | Backend service resources. | google_compute_backend_service | | [groups.tf](./groups.tf) | None | google_compute_instance_group | | [health-check.tf](./health-check.tf) | Health check resource. | google_compute_health_check | -| [main.tf](./main.tf) | Module-level locals and resources. | google_compute_global_forwarding_rule · google_compute_network_endpoint · google_compute_network_endpoint_group · google_compute_region_network_endpoint_group · google_compute_target_http_proxy · google_compute_target_https_proxy | +| [main.tf](./main.tf) | Module-level locals and resources. | google_compute_global_forwarding_rule · google_compute_network_endpoint · google_compute_network_endpoint_group · google_compute_region_network_endpoint_group · google_compute_service_attachment · google_compute_target_http_proxy · google_compute_target_https_proxy | | [outputs.tf](./outputs.tf) | Module outputs. | | | [urlmap.tf](./urlmap.tf) | URL map resources. | google_compute_url_map | | [variables-backend-service.tf](./variables-backend-service.tf) | Backend services variables. | | @@ -753,7 +821,7 @@ When deploying changes to load balancer configuration please refer to [net-lb-ap |---|---|:---:|:---:|:---:| | [name](variables.tf#L72) | Load balancer name. | string | ✓ | | | [project_id](variables.tf#L153) | Project id. | string | ✓ | | -| [vpc_config](variables.tf#L180) | VPC-level configuration. | object({…}) | ✓ | | +| [vpc_config](variables.tf#L195) | VPC-level configuration. | object({…}) | ✓ | | | [addresses](variables.tf#L17) | Optional IP address used for the forwarding rule. | map(string) | | null | | [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…})) | | {} | | [description](variables.tf#L23) | Optional description used for resources. | string | | "Terraform managed." | @@ -765,7 +833,8 @@ When deploying changes to load balancer configuration please refer to [net-lb-ap | [neg_configs](variables.tf#L77) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | | [ports](variables.tf#L143) | Optional ports for HTTP load balancer. | list(string) | | null | | [protocol](variables.tf#L158) | Protocol supported by this load balancer. | string | | "HTTP" | -| [service_directory_registration](variables.tf#L171) | Service directory namespace and service used to register this load balancer. | object({…}) | | null | +| [service_attachment](variables.tf#L171) | PSC service attachments. | object({…}) | | null | +| [service_directory_registration](variables.tf#L186) | Service directory namespace and service used to register this load balancer. | object({…}) | | null | | [urlmap_config](variables-urlmap.tf#L19) | The URL map configuration. | object({…}) | | {…} | ## Outputs diff --git a/modules/net-lb-app-int-cross-region/main.tf b/modules/net-lb-app-int-cross-region/main.tf index 28d00b9a4..0d2eec43f 100644 --- a/modules/net-lb-app-int-cross-region/main.tf +++ b/modules/net-lb-app-int-cross-region/main.tf @@ -99,6 +99,37 @@ resource "google_compute_target_https_proxy" "default" { url_map = google_compute_url_map.default.id } +resource "google_compute_service_attachment" "default" { + for_each = var.service_attachment == null ? {} : google_compute_global_forwarding_rule.forwarding_rules + project = var.project_id + region = each.key + name = each.value.name + description = var.service_attachment.description + target_service = each.value.id + nat_subnets = var.service_attachment.nat_subnets[each.key] + connection_preference = ( + var.service_attachment.automatic_connection + ? "ACCEPT_AUTOMATIC" + : "ACCEPT_MANUAL" + ) + consumer_reject_lists = var.service_attachment.consumer_reject_lists + domain_names = ( + var.service_attachment.domain_name == null + ? null + : [var.service_attachment.domain_name[each.key]] + ) + enable_proxy_protocol = var.service_attachment.enable_proxy_protocol + reconcile_connections = var.service_attachment.reconcile_connections + dynamic "consumer_accept_lists" { + for_each = var.service_attachment.consumer_accept_lists + iterator = accept + content { + project_id_or_num = accept.key + connection_limit = accept.value + } + } +} + resource "google_compute_network_endpoint_group" "default" { for_each = local.neg_zonal project = ( diff --git a/modules/net-lb-app-int-cross-region/variables.tf b/modules/net-lb-app-int-cross-region/variables.tf index ac9471858..02eadbd9d 100644 --- a/modules/net-lb-app-int-cross-region/variables.tf +++ b/modules/net-lb-app-int-cross-region/variables.tf @@ -168,6 +168,21 @@ variable "protocol" { } } +variable "service_attachment" { + description = "PSC service attachments." + type = object({ + automatic_connection = optional(bool, false) + consumer_accept_lists = optional(map(string), {}) + consumer_reject_lists = optional(list(string)) + description = optional(string) + domain_name = optional(map(string)) + enable_proxy_protocol = optional(bool, false) + nat_subnets = map(list(string)) + reconcile_connections = optional(bool) + }) + default = null +} + variable "service_directory_registration" { description = "Service directory namespace and service used to register this load balancer." type = object({ diff --git a/tests/modules/agent_engine/assets/src/agent.py b/tests/modules/agent_engine/assets/src/agent.py index 1cea69c4c..d928375a0 100644 --- a/tests/modules/agent_engine/assets/src/agent.py +++ b/tests/modules/agent_engine/assets/src/agent.py @@ -42,4 +42,4 @@ root_agent = LlmAgent( tools=[get_exchange_rate], ) -local_agent = AdkApp(agent=root_agent) +agent = AdkApp(agent=root_agent) diff --git a/tests/modules/agent_engine/assets/src/source.tar.gz b/tests/modules/agent_engine/assets/src/source.tar.gz new file mode 100644 index 000000000..d8a8f24bd Binary files /dev/null and b/tests/modules/agent_engine/assets/src/source.tar.gz differ diff --git a/tests/modules/agent_engine/examples/encryption.yaml b/tests/modules/agent_engine/examples/encryption.yaml index d0c02a74c..6f319226c 100644 --- a/tests/modules/agent_engine/examples/encryption.yaml +++ b/tests/modules/agent_engine/examples/encryption.yaml @@ -38,86 +38,7 @@ values: member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com project: project-id timeouts: null - module.agent_engine.google_storage_bucket.default[0]: - autoclass: [] - cors: [] - custom_placement_config: [] - default_event_based_hold: null - effective_labels: - goog-terraform-provisioned: 'true' - enable_object_retention: null - encryption: [] - force_destroy: false - hierarchical_namespace: [] - ip_filter: [] - labels: null - lifecycle_rule: [] - location: EUROPE-WEST8 - logging: [] - name: my-agent - project: project-id - requester_pays: null - retention_policy: [] - storage_class: STANDARD - terraform_labels: - goog-terraform-provisioned: 'true' - timeouts: null - uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: dependencies.tar.gz - retention: [] - source: assets/src//dependencies.tar.gz - source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.pickle_from_src[0]: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: pickle.pkl - retention: [] - source: assets/src//pickle.pkl - source_md5hash: 493cf9bf3e59e39913e61916549f95a5 - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: requirements.txt - retention: [] - source: assets/src//requirements.txt - source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff - temporary_hold: null - timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: @@ -128,15 +49,17 @@ values: - agent_framework: google-adk class_methods: null deployment_spec: [] - package_spec: - - dependency_files_gcs_uri: gs://my-agent/dependencies.tar.gz - pickle_object_gcs_uri: gs://my-agent/pickle.pkl - python_version: '3.12' - requirements_gcs_uri: gs://my-agent/requirements.txt + package_spec: [] service_account: my-agent@project-id.iam.gserviceaccount.com + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' timeouts: null - module.agent_engine.null_resource.default[0]: - triggers: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m destroy_duration: null @@ -145,12 +68,9 @@ values: counts: google_project_iam_member: 3 google_service_account: 1 - google_storage_bucket: 1 - google_storage_bucket_object: 3 google_vertex_ai_reasoning_engine: 1 modules: 1 - null_resource: 1 - resources: 11 + resources: 6 time_sleep: 1 outputs: {} diff --git a/tests/modules/agent_engine/examples/environment.yaml b/tests/modules/agent_engine/examples/environment.yaml index a92d3d1e6..dfd2b5a61 100644 --- a/tests/modules/agent_engine/examples/environment.yaml +++ b/tests/modules/agent_engine/examples/environment.yaml @@ -38,86 +38,7 @@ values: member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com project: project-id timeouts: null - module.agent_engine.google_storage_bucket.default[0]: - autoclass: [] - cors: [] - custom_placement_config: [] - default_event_based_hold: null - effective_labels: - goog-terraform-provisioned: 'true' - enable_object_retention: null - encryption: [] - force_destroy: false - hierarchical_namespace: [] - ip_filter: [] - labels: null - lifecycle_rule: [] - location: EUROPE-WEST8 - logging: [] - name: my-agent - project: project-id - requester_pays: null - retention_policy: [] - storage_class: STANDARD - terraform_labels: - goog-terraform-provisioned: 'true' - timeouts: null - uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: dependencies.tar.gz - retention: [] - source: assets/src//dependencies.tar.gz - source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.pickle_from_src[0]: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: pickle.pkl - retention: [] - source: assets/src//pickle.pkl - source_md5hash: 493cf9bf3e59e39913e61916549f95a5 - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: requirements.txt - retention: [] - source: assets/src//requirements.txt - source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff - temporary_hold: null - timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: [] @@ -135,15 +56,17 @@ values: secret_ref: - secret: projects/YOUR_PROJECT_NUMBER/secrets/my-bar-secret version: latest - package_spec: - - dependency_files_gcs_uri: gs://my-agent/dependencies.tar.gz - pickle_object_gcs_uri: gs://my-agent/pickle.pkl - python_version: '3.12' - requirements_gcs_uri: gs://my-agent/requirements.txt + package_spec: [] service_account: my-agent@project-id.iam.gserviceaccount.com + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' timeouts: null - module.agent_engine.null_resource.default[0]: - triggers: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m destroy_duration: null @@ -152,12 +75,9 @@ values: counts: google_project_iam_member: 3 google_service_account: 1 - google_storage_bucket: 1 - google_storage_bucket_object: 3 google_vertex_ai_reasoning_engine: 1 modules: 1 - null_resource: 1 - resources: 11 + resources: 6 time_sleep: 1 outputs: {} diff --git a/tests/modules/agent_engine/examples/minimal-pickle.yaml b/tests/modules/agent_engine/examples/minimal-pickle.yaml index 8cb0cd285..e63942921 100644 --- a/tests/modules/agent_engine/examples/minimal-pickle.yaml +++ b/tests/modules/agent_engine/examples/minimal-pickle.yaml @@ -63,12 +63,13 @@ values: goog-terraform-provisioned: 'true' timeouts: null uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: + module.agent_engine.google_storage_bucket_object.dependencies[0]: bucket: my-agent cache_control: null content_disposition: null content_encoding: null content_language: null + contexts: [] customer_encryption: [] deletion_policy: null detect_md5hash: null @@ -77,7 +78,7 @@ values: metadata: null name: dependencies.tar.gz retention: [] - source: assets/src//dependencies.tar.gz + source: assets/src/dependencies.tar.gz source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a temporary_hold: null timeouts: null @@ -87,6 +88,7 @@ values: content_disposition: null content_encoding: null content_language: null + contexts: [] customer_encryption: [] deletion_policy: null detect_md5hash: null @@ -95,16 +97,17 @@ values: metadata: null name: pickle.pkl retention: [] - source: assets/src//pickle.pkl + source: assets/src/pickle.pkl source_md5hash: 493cf9bf3e59e39913e61916549f95a5 temporary_hold: null timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: + module.agent_engine.google_storage_bucket_object.requirements[0]: bucket: my-agent cache_control: null content_disposition: null content_encoding: null content_language: null + contexts: [] customer_encryption: [] deletion_policy: null detect_md5hash: null @@ -113,11 +116,11 @@ values: metadata: null name: requirements.txt retention: [] - source: assets/src//requirements.txt + source: assets/src/requirements.txt source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff temporary_hold: null timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: [] @@ -133,6 +136,7 @@ values: python_version: '3.12' requirements_gcs_uri: gs://my-agent/requirements.txt service_account: my-agent@project-id.iam.gserviceaccount.com + source_code_spec: [] timeouts: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m diff --git a/tests/modules/agent_engine/examples/minimal.yaml b/tests/modules/agent_engine/examples/minimal.yaml index ba1a04600..02fa8092d 100644 --- a/tests/modules/agent_engine/examples/minimal.yaml +++ b/tests/modules/agent_engine/examples/minimal.yaml @@ -38,86 +38,7 @@ values: member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com project: project-id timeouts: null - module.agent_engine.google_storage_bucket.default[0]: - autoclass: [] - cors: [] - custom_placement_config: [] - default_event_based_hold: null - effective_labels: - goog-terraform-provisioned: 'true' - enable_object_retention: null - encryption: [] - force_destroy: false - hierarchical_namespace: [] - ip_filter: [] - labels: null - lifecycle_rule: [] - location: EUROPE-WEST8 - logging: [] - name: my-agent - project: project-id - requester_pays: null - retention_policy: [] - storage_class: STANDARD - terraform_labels: - goog-terraform-provisioned: 'true' - timeouts: null - uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: dependencies.tar.gz - retention: [] - source: assets/src//dependencies.tar.gz - source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.pickle_from_src[0]: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: pickle.pkl - retention: [] - source: assets/src//pickle.pkl - source_md5hash: 493cf9bf3e59e39913e61916549f95a5 - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: requirements.txt - retention: [] - source: assets/src//requirements.txt - source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff - temporary_hold: null - timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: [] @@ -127,15 +48,17 @@ values: - agent_framework: google-adk class_methods: null deployment_spec: [] - package_spec: - - dependency_files_gcs_uri: gs://my-agent/dependencies.tar.gz - pickle_object_gcs_uri: gs://my-agent/pickle.pkl - python_version: '3.12' - requirements_gcs_uri: gs://my-agent/requirements.txt + package_spec: [] service_account: my-agent@project-id.iam.gserviceaccount.com + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' timeouts: null - module.agent_engine.null_resource.default[0]: - triggers: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m destroy_duration: null @@ -144,12 +67,9 @@ values: counts: google_project_iam_member: 3 google_service_account: 1 - google_storage_bucket: 1 - google_storage_bucket_object: 3 google_vertex_ai_reasoning_engine: 1 modules: 1 - null_resource: 1 - resources: 11 + resources: 6 time_sleep: 1 outputs: {} diff --git a/tests/modules/agent_engine/examples/sa-custom.yaml b/tests/modules/agent_engine/examples/sa-custom.yaml index e8778ebb6..9679cc7e7 100644 --- a/tests/modules/agent_engine/examples/sa-custom.yaml +++ b/tests/modules/agent_engine/examples/sa-custom.yaml @@ -13,86 +13,7 @@ # limitations under the License. values: - module.agent_engine.google_storage_bucket.default[0]: - autoclass: [] - cors: [] - custom_placement_config: [] - default_event_based_hold: null - effective_labels: - goog-terraform-provisioned: 'true' - enable_object_retention: null - encryption: [] - force_destroy: false - hierarchical_namespace: [] - ip_filter: [] - labels: null - lifecycle_rule: [] - location: EUROPE-WEST8 - logging: [] - name: my-agent - project: project-id - requester_pays: null - retention_policy: [] - storage_class: STANDARD - terraform_labels: - goog-terraform-provisioned: 'true' - timeouts: null - uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: dependencies.tar.gz - retention: [] - source: assets/src//dependencies.tar.gz - source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.pickle_from_src[0]: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: pickle.pkl - retention: [] - source: assets/src//pickle.pkl - source_md5hash: 493cf9bf3e59e39913e61916549f95a5 - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: requirements.txt - retention: [] - source: assets/src//requirements.txt - source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff - temporary_hold: null - timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: [] @@ -102,27 +23,26 @@ values: - agent_framework: google-adk class_methods: null deployment_spec: [] - package_spec: - - dependency_files_gcs_uri: gs://my-agent/dependencies.tar.gz - pickle_object_gcs_uri: gs://my-agent/pickle.pkl - python_version: '3.12' - requirements_gcs_uri: gs://my-agent/requirements.txt + package_spec: [] service_account: my-sa@project-id.iam.gserviceaccount.com + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' timeouts: null - module.agent_engine.null_resource.default[0]: - triggers: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m destroy_duration: null triggers: null counts: - google_storage_bucket: 1 - google_storage_bucket_object: 3 google_vertex_ai_reasoning_engine: 1 modules: 1 - null_resource: 1 - resources: 7 + resources: 2 time_sleep: 1 outputs: {} diff --git a/tests/modules/agent_engine/examples/sa-default.yaml b/tests/modules/agent_engine/examples/sa-default.yaml index d843ee1a8..768175f47 100644 --- a/tests/modules/agent_engine/examples/sa-default.yaml +++ b/tests/modules/agent_engine/examples/sa-default.yaml @@ -13,86 +13,7 @@ # limitations under the License. values: - module.agent_engine.google_storage_bucket.default[0]: - autoclass: [] - cors: [] - custom_placement_config: [] - default_event_based_hold: null - effective_labels: - goog-terraform-provisioned: 'true' - enable_object_retention: null - encryption: [] - force_destroy: false - hierarchical_namespace: [] - ip_filter: [] - labels: null - lifecycle_rule: [] - location: EUROPE-WEST8 - logging: [] - name: my-agent - project: project-id - requester_pays: null - retention_policy: [] - storage_class: STANDARD - terraform_labels: - goog-terraform-provisioned: 'true' - timeouts: null - uniform_bucket_level_access: true - module.agent_engine.google_storage_bucket_object.dependencies: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: dependencies.tar.gz - retention: [] - source: assets/src//dependencies.tar.gz - source_md5hash: 49a4c43e6bef605c2fa6ddabac48ba6a - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.pickle_from_src[0]: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: pickle.pkl - retention: [] - source: assets/src//pickle.pkl - source_md5hash: 493cf9bf3e59e39913e61916549f95a5 - temporary_hold: null - timeouts: null - module.agent_engine.google_storage_bucket_object.requirements: - bucket: my-agent - cache_control: null - content_disposition: null - content_encoding: null - content_language: null - customer_encryption: [] - deletion_policy: null - detect_md5hash: null - event_based_hold: null - force_empty_content_type: null - metadata: null - name: requirements.txt - retention: [] - source: assets/src//requirements.txt - source_md5hash: 0acf2b14e855722af60e03e8fa8b04ff - temporary_hold: null - timeouts: null - module.agent_engine.google_vertex_ai_reasoning_engine.default: + module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]: description: Terraform managed. display_name: my-agent encryption_spec: [] @@ -102,27 +23,26 @@ values: - agent_framework: google-adk class_methods: null deployment_spec: [] - package_spec: - - dependency_files_gcs_uri: gs://my-agent/dependencies.tar.gz - pickle_object_gcs_uri: gs://my-agent/pickle.pkl - python_version: '3.12' - requirements_gcs_uri: gs://my-agent/requirements.txt + package_spec: [] service_account: null + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' timeouts: null - module.agent_engine.null_resource.default[0]: - triggers: null module.agent_engine.time_sleep.wait_5_minutes: create_duration: 5m destroy_duration: null triggers: null counts: - google_storage_bucket: 1 - google_storage_bucket_object: 3 google_vertex_ai_reasoning_engine: 1 modules: 1 - null_resource: 1 - resources: 7 + resources: 2 time_sleep: 1 outputs: {} diff --git a/tests/modules/agent_engine/examples/unmanaged.yaml b/tests/modules/agent_engine/examples/unmanaged.yaml new file mode 100644 index 000000000..30f8f50a2 --- /dev/null +++ b/tests/modules/agent_engine/examples/unmanaged.yaml @@ -0,0 +1,75 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + module.agent_engine.google_project_iam_member.default["roles/aiplatform.user"]: + condition: [] + member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com + project: project-id + role: roles/aiplatform.user + module.agent_engine.google_project_iam_member.default["roles/storage.objectViewer"]: + condition: [] + member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com + project: project-id + role: roles/storage.objectViewer + module.agent_engine.google_project_iam_member.default["roles/viewer"]: + condition: [] + member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com + project: project-id + role: roles/viewer + module.agent_engine.google_service_account.service_account[0]: + account_id: my-agent + create_ignore_already_exists: null + description: null + disabled: false + display_name: my-agent + email: my-agent@project-id.iam.gserviceaccount.com + member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com + project: project-id + timeouts: null + module.agent_engine.google_vertex_ai_reasoning_engine.unmanaged[0]: + description: Terraform managed. + display_name: my-agent + encryption_spec: [] + project: project-id + region: europe-west8 + spec: + - agent_framework: google-adk + class_methods: null + deployment_spec: [] + package_spec: [] + service_account: my-agent@project-id.iam.gserviceaccount.com + source_code_spec: + - inline_source: + - source_archive: H4sIAMCUSmkAA+1Y727bNhB3CwzbtM/b55v7oQmQyPprJyk8QE2y1ahrZ7HTriiKgJFom4skqhRV2yj6Hvu8PdL2AgP2CHuAHWXZiZP+C5C4WKsfQNjiHY+/I3l3og7I5AElARU1/VjQFxkTNKKxTHU5kZVrgmEYdceBSiMHVCy34Vo2qP4ZXAdM17Qs1eomGJZp160KTK6LwLuQpZIIpBJmPkkElfQteolgERHToeBZ8ib5zBNY/P5PYDqQsaC5ZWw5DUuzDYgki2jTbNTrzrbrGNt6fatuGbhljvaxuZa4ftxc1J9hHv+24dqGbVyKf8uxl+PfbNgNtwLG9VO5jM88/itffPdl5Xal8oj40O3BL1BA9VW+xmZhe4FNPf/xYSa9fv+w+KtG/Ibtmwsqt876v/V5pJMkCameCP6SxiT2aeXW7cpf//z+1b9/b/15DU6WeBsOFvX/5vLA++o/Bv3F+m869bL+rwJXqf9uA9qt+97h7oPW4319QqQU+puCt+n93PLMbo/tHvRH3c4jzdmGHg5qP33XoHMRX75prAw3X/3fX//Ni/FvNsy6Udb/VWDI+TCkm37Is2CTsCQkcsBF9IwM8UQc03jIYpo+/6Fp6qZl6IZW6JPgNO9zdVPLxybMPw1ps2nrSutje1XiQ3Fw7v6f77meTK97jivc/03LdVX8u65R1v9V4J3139natnXbMvA2ZrlbZVR/gri5qD/DFe7/Rfy7bt0u6/9KUN7/P2uc1f+bywNXuP/P679tO2X9XwWuUv/L+/+nh5uv/u+t/5btXIx/13adsv6vAne+r2WpqJ2wuEbjl5BM5YjHtqbdgV2eTAUbjiSoz3/wU37xh3Z7V7uD0jbzaZzSALIYiwfIEQUvIT7+FJINeExFyngMlm7AmlKoFqLq+j20MOUZRGQKMZeQpRRNsBQGDOegE58mElgMmCiSkKn0AGMmR/k0hREdTTwtTPATSVCboH6CT4PzekBkTlhhJGWS7tRq4/EY849iq3MxrIUzzbTWbu3ud3r7m8g4H3MUhzRNofhGFsDJFFTaYj45QZohGQMXQIaCokxyRXgsmGTxcANSPpBjIihaCVgqBTvJ5NJqzemh0+cVcL1IDFWvB61eFe57vVZvA208afUfdI/68MQ7PPQ6/dZ+D7qHsNvt7LX6rW4Hn34Er/MUHrY6extAca1wGjrBA438kSRT60gDtWg9SpcIDPiMUJpQnw2Yj37FwwzzAgwxN4sY3YGEioilajdTpBeglZBFTBKZ91xySte0geARzD4W6SQ41fM8kyoeXEhoh5GnOmZqOIukE8L0pY9Oc10vOPWSRNO0gA5gSFE+8UdIkR4LIumapjbWz4SgsT89VvZ2AJcTmlA96u1VN5blki+k+0eHF6UBGlzIQ3xIJaqs76BWQUYdBexNsQeXNuFqAZuLXh3pzQgBDKrz00YSpg8EiU8HGfopVOWrvVqa83VBBCAhgkRp85UGC1SVT9WdZR83zitIfl4seSF7rZTWc6YyE/GCsP5ryuO1dS0PckFxfvD2HkK++EWYcR6mmuBczm6H6OJ8x2buRTygYbM6pBGLGYaLuzkISToq3GAxLmHmq8PRrKoYxTjA4BzRMBlkIRA8SJh0Y1moxwRfOO4u+C+2N5/67kwnZ9R8dmn7n+P2aNqc5OyorOWPzTP66+X7RIkSJUpcwn+2Vos4ACgAAA== + python_spec: + - entrypoint_module: agent + entrypoint_object: agent + requirements_file: requirements.txt + version: '3.12' + timeouts: null + module.agent_engine.time_sleep.wait_5_minutes: + create_duration: 5m + destroy_duration: null + triggers: null + +counts: + google_project_iam_member: 3 + google_service_account: 1 + google_vertex_ai_reasoning_engine: 1 + modules: 1 + resources: 6 + time_sleep: 1 + +outputs: {}