// 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.

syntax = "proto3";

package google.cloud.aiplatform.v1beta1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/aiplatform/v1beta1/encryption_spec.proto";
import "google/cloud/aiplatform/v1beta1/machine_resources.proto";
import "google/cloud/aiplatform/v1beta1/service_networking.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.AIPlatform.V1Beta1";
option go_package = "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb;aiplatformpb";
option java_multiple_files = true;
option java_outer_classname = "IndexEndpointProto";
option java_package = "com.google.cloud.aiplatform.v1beta1";
option php_namespace = "Google\\Cloud\\AIPlatform\\V1beta1";
option ruby_package = "Google::Cloud::AIPlatform::V1beta1";

// Indexes are deployed into it. An IndexEndpoint can have multiple
// DeployedIndexes.
message IndexEndpoint {
  option (google.api.resource) = {
    type: "aiplatform.googleapis.com/IndexEndpoint"
    pattern: "projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}"
  };

  // Output only. The resource name of the IndexEndpoint.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The display name of the IndexEndpoint.
  // The name can be up to 128 characters long and can consist of any UTF-8
  // characters.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // The description of the IndexEndpoint.
  string description = 3;

  // Output only. The indexes deployed in this endpoint.
  repeated DeployedIndex deployed_indexes = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Used to perform consistent read-modify-write updates. If not set, a blind
  // "overwrite" update happens.
  string etag = 5;

  // The labels with user-defined metadata to organize your IndexEndpoints.
  //
  // Label keys and values can be no longer than 64 characters
  // (Unicode codepoints), can only contain lowercase letters, numeric
  // characters, underscores and dashes. International characters are allowed.
  //
  // See https://goo.gl/xmQnxf for more information and examples of labels.
  map<string, string> labels = 6;

  // Output only. Timestamp when this IndexEndpoint was created.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when this IndexEndpoint was last updated.
  // This timestamp is not updated when the endpoint's DeployedIndexes are
  // updated, e.g. due to updates of the original Indexes they are the
  // deployments of.
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The full name of the Google Compute Engine
  // [network](https://cloud.google.com/compute/docs/networks-and-firewalls#networks)
  // to which the IndexEndpoint should be peered.
  //
  // Private services access must already be configured for the network. If left
  // unspecified, the Endpoint is not peered with any network.
  //
  // [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] and
  // [private_service_connect_config][google.cloud.aiplatform.v1beta1.IndexEndpoint.private_service_connect_config]
  // are mutually exclusive.
  //
  // [Format](https://cloud.google.com/compute/docs/reference/rest/v1/networks/insert):
  // `projects/{project}/global/networks/{network}`.
  // Where {project} is a project number, as in '12345', and {network} is
  // network name.
  string network = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Deprecated: If true, expose the IndexEndpoint via private service
  // connect.
  //
  // Only one of the fields,
  // [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] or
  // [enable_private_service_connect][google.cloud.aiplatform.v1beta1.IndexEndpoint.enable_private_service_connect],
  // can be set.
  bool enable_private_service_connect = 10
      [deprecated = true, (google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration for private service connect.
  //
  // [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] and
  // [private_service_connect_config][google.cloud.aiplatform.v1beta1.IndexEndpoint.private_service_connect_config]
  // are mutually exclusive.
  PrivateServiceConnectConfig private_service_connect_config = 12
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If true, the deployed index will be accessible through public
  // endpoint.
  bool public_endpoint_enabled = 13 [(google.api.field_behavior) = OPTIONAL];

  // Output only. If
  // [public_endpoint_enabled][google.cloud.aiplatform.v1beta1.IndexEndpoint.public_endpoint_enabled]
  // is true, this field will be populated with the domain name to use for this
  // index endpoint.
  string public_endpoint_domain_name = 14
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. Customer-managed encryption key spec for an IndexEndpoint. If
  // set, this IndexEndpoint and all sub-resources of this IndexEndpoint will be
  // secured by this key.
  EncryptionSpec encryption_spec = 15 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. Reserved for future use.
  bool satisfies_pzs = 17 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Reserved for future use.
  bool satisfies_pzi = 18 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A deployment of an Index. IndexEndpoints contain one or more DeployedIndexes.
message DeployedIndex {
  // Required. The user specified ID of the DeployedIndex.
  // The ID can be up to 128 characters long and must start with a letter and
  // only contain letters, numbers, and underscores.
  // The ID must be unique within the project it is created in.
  string id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The name of the Index this is the deployment of.
  // We may refer to this Index as the DeployedIndex's "original" Index.
  string index = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Index"
    }
  ];

  // The display name of the DeployedIndex. If not provided upon creation,
  // the Index's display_name is used.
  string display_name = 3;

  // Output only. Timestamp when the DeployedIndex was created.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Provides paths for users to send requests directly to the
  // deployed index services running on Cloud via private services access. This
  // field is populated if
  // [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] is
  // configured.
  IndexPrivateEndpoints private_endpoints = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The DeployedIndex may depend on various data on its original
  // Index. Additionally when certain changes to the original Index are being
  // done (e.g. when what the Index contains is being changed) the DeployedIndex
  // may be asynchronously updated in the background to reflect these changes.
  // If this timestamp's value is at least the
  // [Index.update_time][google.cloud.aiplatform.v1beta1.Index.update_time] of
  // the original Index, it means that this DeployedIndex and the original Index
  // are in sync. If this timestamp is older, then to see which updates this
  // DeployedIndex already contains (and which it does not), one must
  // [list][google.longrunning.Operations.ListOperations] the operations that
  // are running on the original Index. Only the successfully completed
  // Operations with
  // [update_time][google.cloud.aiplatform.v1beta1.GenericOperationMetadata.update_time]
  // equal or before this sync time are contained in this DeployedIndex.
  google.protobuf.Timestamp index_sync_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. A description of resources that the DeployedIndex uses, which to
  // large degree are decided by Vertex AI, and optionally allows only a modest
  // additional configuration.
  // If min_replica_count is not set, the default value is 2 (we don't provide
  // SLA when min_replica_count=1). If max_replica_count is not set, the
  // default value is min_replica_count. The max allowed replica count is
  // 1000.
  AutomaticResources automatic_resources = 7
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. A description of resources that are dedicated to the
  // DeployedIndex, and that need a higher degree of manual configuration. The
  // field min_replica_count must be set to a value strictly greater than 0, or
  // else validation will fail. We don't provide SLA when min_replica_count=1.
  // If max_replica_count is not set, the default value is min_replica_count.
  // The max allowed replica count is 1000.
  //
  // Available machine types for SMALL shard:
  // e2-standard-2 and all machine types available for MEDIUM and LARGE shard.
  //
  // Available machine types for MEDIUM shard:
  // e2-standard-16 and all machine types available for LARGE shard.
  //
  // Available machine types for LARGE shard:
  // e2-highmem-16, n2d-standard-32.
  //
  // n1-standard-16 and n1-standard-32 are still available, but we recommend
  // e2-standard-16 and e2-highmem-16 for cost efficiency.
  DedicatedResources dedicated_resources = 16
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If true, private endpoint's access logs are sent to Cloud
  // Logging.
  //
  // These logs are like standard server access logs, containing
  // information like timestamp and latency for each MatchRequest.
  //
  // Note that logs may incur a cost, especially if the deployed
  // index receives a high queries per second rate (QPS).
  // Estimate your costs before enabling this option.
  bool enable_access_logging = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set, the authentication is enabled for the private endpoint.
  DeployedIndexAuthConfig deployed_index_auth_config = 9
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. A list of reserved ip ranges under the VPC network that can be
  // used for this DeployedIndex.
  //
  // If set, we will deploy the index within the provided ip ranges. Otherwise,
  // the index might be deployed to any ip ranges under the provided VPC
  // network.
  //
  // The value should be the name of the address
  // (https://cloud.google.com/compute/docs/reference/rest/v1/addresses)
  // Example: ['vertex-ai-ip-range'].
  //
  // For more information about subnets and network IP ranges, please see
  // https://cloud.google.com/vpc/docs/subnets#manually_created_subnet_ip_ranges.
  repeated string reserved_ip_ranges = 10
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The deployment group can be no longer than 64 characters (eg:
  // 'test', 'prod'). If not set, we will use the 'default' deployment group.
  //
  // Creating `deployment_groups` with `reserved_ip_ranges` is a recommended
  // practice when the peered network has multiple peering ranges. This creates
  // your deployments from predictable IP spaces for easier traffic
  // administration. Also, one deployment_group (except 'default') can only be
  // used with the same reserved_ip_ranges which means if the deployment_group
  // has been used with reserved_ip_ranges: [a, b, c], using it with [a, b] or
  // [d, e] is disallowed.
  //
  // Note: we only support up to 5 deployment groups(not including 'default').
  string deployment_group = 11 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set for PSC deployed index, PSC connection will be
  // automatically created after deployment is done and the endpoint information
  // is populated in private_endpoints.psc_automated_endpoints.
  repeated PSCAutomationConfig psc_automation_configs = 19
      [(google.api.field_behavior) = OPTIONAL];
}

// Used to set up the auth on the DeployedIndex's private endpoint.
message DeployedIndexAuthConfig {
  // Configuration for an authentication provider, including support for
  // [JSON Web Token
  // (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32).
  message AuthProvider {
    // The list of JWT
    // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3).
    // that are allowed to access. A JWT containing any of these audiences will
    // be accepted.
    repeated string audiences = 1;

    // A list of allowed JWT issuers. Each entry must be a valid Google
    // service account, in the following format:
    //
    // `service-account-name@project-id.iam.gserviceaccount.com`
    repeated string allowed_issuers = 2;
  }

  // Defines the authentication provider that the DeployedIndex uses.
  AuthProvider auth_provider = 1;
}

// IndexPrivateEndpoints proto is used to provide paths for users to send
// requests via private endpoints (e.g. private service access, private service
// connect).
// To send request via private service access, use match_grpc_address.
// To send request via private service connect, use service_attachment.
message IndexPrivateEndpoints {
  // Output only. The ip address used to send match gRPC requests.
  string match_grpc_address = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The name of the service attachment resource. Populated if
  // private service connect is enabled.
  string service_attachment = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. PscAutomatedEndpoints is populated if private service connect
  // is enabled if PscAutomatedConfig is set.
  repeated PscAutomatedEndpoints psc_automated_endpoints = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
