// Copyright 2024 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.networkconnectivity.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/networkconnectivity/v1/common.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.NetworkConnectivity.V1";
option go_package = "cloud.google.com/go/networkconnectivity/apiv1/networkconnectivitypb;networkconnectivitypb";
option java_multiple_files = true;
option java_outer_classname = "PolicyBasedRoutingProto";
option java_package = "com.google.cloud.networkconnectivity.v1";
option php_namespace = "Google\\Cloud\\NetworkConnectivity\\V1";
option ruby_package = "Google::Cloud::NetworkConnectivity::V1";

// Policy-Based Routing allows GCP customers to specify flexibile routing
// policies for Layer 4 traffic traversing through the connected service.
service PolicyBasedRoutingService {
  option (google.api.default_host) = "networkconnectivity.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists PolicyBasedRoutes in a given project and location.
  rpc ListPolicyBasedRoutes(ListPolicyBasedRoutesRequest)
      returns (ListPolicyBasedRoutesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/global}/policyBasedRoutes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details of a single PolicyBasedRoute.
  rpc GetPolicyBasedRoute(GetPolicyBasedRouteRequest)
      returns (PolicyBasedRoute) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/policyBasedRoutes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new PolicyBasedRoute in a given project and location.
  rpc CreatePolicyBasedRoute(CreatePolicyBasedRouteRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/global}/policyBasedRoutes"
      body: "policy_based_route"
    };
    option (google.api.method_signature) =
        "parent,policy_based_route,policy_based_route_id";
    option (google.longrunning.operation_info) = {
      response_type: "PolicyBasedRoute"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a single PolicyBasedRoute.
  rpc DeletePolicyBasedRoute(DeletePolicyBasedRouteRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/global/policyBasedRoutes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }
}

// Policy Based Routes (PBR) are more powerful routes that allows GCP customers
// to route their L4 network traffic based on not just destination IP, but also
// source IP, protocol and more. A PBR always take precedence when it conflicts
// with other types of routes.
// Next id: 22
message PolicyBasedRoute {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/PolicyBasedRoute"
    pattern: "projects/{project}/locations/global/PolicyBasedRoutes/{policy_based_route}"
  };

  // VM instances to which this policy based route applies to.
  message VirtualMachine {
    // Optional. A list of VM instance tags to which this policy based route
    // applies to. VM instances that have ANY of tags specified here will
    // install this PBR.
    repeated string tags = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // InterconnectAttachment to which this route applies to.
  message InterconnectAttachment {
    // Optional. Cloud region to install this policy based route on interconnect
    // attachment. Use `all` to install it on all interconnect attachments.
    string region = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Filter matches L4 traffic.
  message Filter {
    // The internet protocol version.
    enum ProtocolVersion {
      // Default value.
      PROTOCOL_VERSION_UNSPECIFIED = 0;

      // The PBR is for IPv4 internet protocol traffic.
      IPV4 = 1;
    }

    // Optional. The IP protocol that this policy based route applies to. Valid
    // values are 'TCP', 'UDP', and 'ALL'. Default is 'ALL'.
    string ip_protocol = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The source IP range of outgoing packets that this policy based
    // route applies to. Default is "0.0.0.0/0" if protocol version is IPv4.
    string src_range = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The destination IP range of outgoing packets that this policy
    // based route applies to. Default is "0.0.0.0/0" if protocol version is
    // IPv4.
    string dest_range = 3 [(google.api.field_behavior) = OPTIONAL];

    // Required. Internet protocol versions this policy based route applies to.
    // For this version, only IPV4 is supported.
    ProtocolVersion protocol_version = 6
        [(google.api.field_behavior) = REQUIRED];
  }

  // Informational warning message.
  message Warnings {
    // Warning code for Policy Based Routing. Expect to add values in the
    // future.
    enum Code {
      // Default value.
      WARNING_UNSPECIFIED = 0;

      // The policy based route is not active and functioning. Common causes are
      // the dependent network was deleted or the resource project was turned
      // off.
      RESOURCE_NOT_ACTIVE = 1;

      // The policy based route is being modified (e.g. created/deleted) at this
      // time.
      RESOURCE_BEING_MODIFIED = 2;
    }

    // Output only. A warning code, if applicable.
    Code code = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Metadata about this warning in key: value format. The key
    // should provides more detail on the warning being returned. For example,
    // for warnings where there are no results in a list request for a
    // particular zone, this key might be scope and the key value might be the
    // zone name. Other examples might be a key indicating a deprecated resource
    // and a suggested replacement.
    map<string, string> data = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. A human-readable description of the warning code.
    string warning_message = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The other routing cases.
  enum OtherRoutes {
    // Default value.
    OTHER_ROUTES_UNSPECIFIED = 0;

    // Use the routes from the default routing tables (system-generated routes,
    // custom routes, peering route) to determine the next hop. This will
    // effectively exclude matching packets being applied on other PBRs with a
    // lower priority.
    DEFAULT_ROUTING = 1;
  }

  // Target specifies network endpoints to which this policy based route applies
  // to. If none of the target is specified, the PBR will be installed on all
  // network endpoints (e.g. VMs, VPNs, and Interconnects) in the VPC.
  oneof target {
    // Optional. VM instances to which this policy based route applies to.
    VirtualMachine virtual_machine = 18
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The interconnect attachments to which this route applies to.
    InterconnectAttachment interconnect_attachment = 9
        [(google.api.field_behavior) = OPTIONAL];
  }

  oneof next_hop {
    // Optional. The IP of a global access enabled L4 ILB that should be the
    // next hop to handle matching packets. For this version, only
    // next_hop_ilb_ip is supported.
    string next_hop_ilb_ip = 12 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Other routes that will be referenced to determine the next hop
    // of the packet.
    OtherRoutes next_hop_other_routes = 21
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Immutable. A unique name of the resource in the form of
  // `projects/{project_number}/locations/global/PolicyBasedRoutes/{policy_based_route_id}`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

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

  // Output only. Time when the PolicyBasedRoute was updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined labels.
  map<string, string> labels = 4;

  // Optional. An optional description of this resource. Provide this field when
  // you create the resource.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. Fully-qualified URL of the network that this route applies to.
  // e.g. projects/my-project/global/networks/my-network.
  string network = 6 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Required. The filter to match L4 traffic.
  Filter filter = 10 [(google.api.field_behavior) = REQUIRED];

  // Optional. The priority of this policy based route. Priority is used to
  // break ties in cases where there are more than one matching policy based
  // routes found. In cases where multiple policy based routes are matched, the
  // one with the lowest-numbered priority value wins. The default value is
  // 1000. The priority value must be from 1 to 65535, inclusive.
  int32 priority = 11 [(google.api.field_behavior) = OPTIONAL];

  // Output only. If potential misconfigurations are detected for this route,
  // this field will be populated with warning messages.
  repeated Warnings warnings = 14 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Server-defined fully-qualified URL for this resource.
  string self_link = 15 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Type of this resource. Always
  // networkconnectivity#policyBasedRoute for Policy Based Route resources.
  string kind = 16 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request for [PolicyBasedRouting.ListPolicyBasedRoutes][] method.
message ListPolicyBasedRoutesRequest {
  // Required. The parent resource's name.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // The maximum number of results per page that should be returned.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // A filter expression that filters the results listed in the response.
  string filter = 4;

  // Sort the results by a certain order.
  string order_by = 5;
}

// Response for [PolicyBasedRouting.ListPolicyBasedRoutes][] method.
message ListPolicyBasedRoutesResponse {
  // Policy based routes to be returned.
  repeated PolicyBasedRoute policy_based_routes = 1;

  // The next pagination token in the List response. It should be used as
  // page_token for the following request. An empty value means no more result.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// Request for [PolicyBasedRouting.GetPolicyBasedRoute][] method.
message GetPolicyBasedRouteRequest {
  // Required. Name of the PolicyBasedRoute resource to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/PolicyBasedRoute"
    }
  ];
}

// Request for [PolicyBasedRouting.CreatePolicyBasedRoute][] method.
message CreatePolicyBasedRouteRequest {
  // Required. The parent resource's name of the PolicyBasedRoute.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. Unique id for the Policy Based Route to create.
  string policy_based_route_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Initial values for a new Policy Based Route.
  PolicyBasedRoute policy_based_route = 3
      [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes since the first request.
  //
  // For example, consider a situation where you make an initial request and
  // the request times out. If you make the request again with the same request
  // ID, the server can check if original operation with the same request ID
  // was received, and if so, will ignore the second request. This prevents
  // clients from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Request for [PolicyBasedRouting.DeletePolicyBasedRoute][] method.
message DeletePolicyBasedRouteRequest {
  // Required. Name of the PolicyBasedRoute resource to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/PolicyBasedRoute"
    }
  ];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes after the first request.
  //
  // For example, consider a situation where you make an initial request and
  // the request times out. If you make the request again with the same request
  // ID, the server can check if original operation with the same request ID
  // was received, and if so, will ignore the second request. This prevents
  // clients from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 2 [(google.api.field_behavior) = OPTIONAL];
}
