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

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/field_info.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/field_mask.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 = "HubProto";
option java_package = "com.google.cloud.networkconnectivity.v1";
option php_namespace = "Google\\Cloud\\NetworkConnectivity\\V1";
option ruby_package = "Google::Cloud::NetworkConnectivity::V1";
option (google.api.resource_definition) = {
  type: "compute.googleapis.com/VpnTunnel"
  pattern: "projects/{project}/regions/{region}/vpnTunnels/{resource_id}"
};
option (google.api.resource_definition) = {
  type: "compute.googleapis.com/Instance"
  pattern: "projects/{project}/zones/{zone}/instances/{instance}"
};

// Network Connectivity Center is a hub-and-spoke abstraction for network
// connectivity management in Google Cloud. It reduces operational complexity
// through a simple, centralized connectivity management model.
service HubService {
  option (google.api.default_host) = "networkconnectivity.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists the Network Connectivity Center hubs associated with a given project.
  rpc ListHubs(ListHubsRequest) returns (ListHubsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/global}/hubs"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about a Network Connectivity Center hub.
  rpc GetHub(GetHubRequest) returns (Hub) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new Network Connectivity Center hub in the specified project.
  rpc CreateHub(CreateHubRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/global}/hubs"
      body: "hub"
    };
    option (google.api.method_signature) = "parent,hub,hub_id";
    option (google.longrunning.operation_info) = {
      response_type: "Hub"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates the description and/or labels of a Network Connectivity Center
  // hub.
  rpc UpdateHub(UpdateHubRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{hub.name=projects/*/locations/global/hubs/*}"
      body: "hub"
    };
    option (google.api.method_signature) = "hub,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Hub"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a Network Connectivity Center hub.
  rpc DeleteHub(DeleteHubRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/global/hubs/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists the Network Connectivity Center spokes associated with a
  // specified hub and location. The list includes both spokes that are attached
  // to the hub and spokes that have been proposed but not yet accepted.
  rpc ListHubSpokes(ListHubSpokesRequest) returns (ListHubSpokesResponse) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*}:listSpokes"
    };
    option (google.api.method_signature) = "name";
  }

  // Query the Private Service Connect propagation status of a Network
  // Connectivity Center hub.
  rpc QueryHubStatus(QueryHubStatusRequest) returns (QueryHubStatusResponse) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*}:queryStatus"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists the Network Connectivity Center spokes in a specified project and
  // location.
  rpc ListSpokes(ListSpokesRequest) returns (ListSpokesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/spokes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about a Network Connectivity Center spoke.
  rpc GetSpoke(GetSpokeRequest) returns (Spoke) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/spokes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a Network Connectivity Center spoke.
  rpc CreateSpoke(CreateSpokeRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/spokes"
      body: "spoke"
    };
    option (google.api.method_signature) = "parent,spoke,spoke_id";
    option (google.longrunning.operation_info) = {
      response_type: "Spoke"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates the parameters of a Network Connectivity Center spoke.
  rpc UpdateSpoke(UpdateSpokeRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{spoke.name=projects/*/locations/*/spokes/*}"
      body: "spoke"
    };
    option (google.api.method_signature) = "spoke,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Spoke"
      metadata_type: "OperationMetadata"
    };
  }

  // Rejects a Network Connectivity Center spoke from being attached to a hub.
  // If the spoke was previously in the `ACTIVE` state, it
  // transitions to the `INACTIVE` state and is no longer able to
  // connect to other spokes that are attached to the hub.
  rpc RejectHubSpoke(RejectHubSpokeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/global/hubs/*}:rejectSpoke"
      body: "*"
    };
    option (google.api.method_signature) = "name,spoke_uri";
    option (google.longrunning.operation_info) = {
      response_type: "RejectHubSpokeResponse"
      metadata_type: "OperationMetadata"
    };
  }

  // Accepts a proposal to attach a Network Connectivity Center spoke
  // to a hub.
  rpc AcceptHubSpoke(AcceptHubSpokeRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/global/hubs/*}:acceptSpoke"
      body: "*"
    };
    option (google.api.method_signature) = "name,spoke_uri";
    option (google.longrunning.operation_info) = {
      response_type: "AcceptHubSpokeResponse"
      metadata_type: "OperationMetadata"
    };
  }

  // Accepts a proposal to update a Network Connectivity Center spoke in a hub.
  rpc AcceptSpokeUpdate(AcceptSpokeUpdateRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/global/hubs/*}:acceptSpokeUpdate"
      body: "*"
    };
    option (google.api.method_signature) = "name,spoke_uri,spoke_etag";
    option (google.longrunning.operation_info) = {
      response_type: "AcceptSpokeUpdateResponse"
      metadata_type: "OperationMetadata"
    };
  }

  // Rejects a proposal to update a Network Connectivity Center spoke in a hub.
  rpc RejectSpokeUpdate(RejectSpokeUpdateRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/global/hubs/*}:rejectSpokeUpdate"
      body: "*"
    };
    option (google.api.method_signature) = "name,spoke_uri,spoke_etag";
    option (google.longrunning.operation_info) = {
      response_type: "RejectSpokeUpdateResponse"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a Network Connectivity Center spoke.
  rpc DeleteSpoke(DeleteSpokeRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/spokes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Gets details about a Network Connectivity Center route table.
  rpc GetRouteTable(GetRouteTableRequest) returns (RouteTable) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*/routeTables/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets details about the specified route.
  rpc GetRoute(GetRouteRequest) returns (Route) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*/routeTables/*/routes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists routes in a given route table.
  rpc ListRoutes(ListRoutesRequest) returns (ListRoutesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/global/hubs/*/routeTables/*}/routes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists route tables in a given hub.
  rpc ListRouteTables(ListRouteTablesRequest)
      returns (ListRouteTablesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/global/hubs/*}/routeTables"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about a Network Connectivity Center group.
  rpc GetGroup(GetGroupRequest) returns (Group) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/global/hubs/*/groups/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists groups in a given hub.
  rpc ListGroups(ListGroupsRequest) returns (ListGroupsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/global/hubs/*}/groups"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates the parameters of a Network Connectivity Center group.
  rpc UpdateGroup(UpdateGroupRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{group.name=projects/*/locations/global/hubs/*/groups/*}"
      body: "group"
    };
    option (google.api.method_signature) = "group,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Group"
      metadata_type: "OperationMetadata"
    };
  }
}

// Supported features for a location
enum LocationFeature {
  // No publicly supported feature in this location
  LOCATION_FEATURE_UNSPECIFIED = 0;

  // Site-to-cloud spokes are supported in this location
  SITE_TO_CLOUD_SPOKES = 1;

  // Site-to-site spokes are supported in this location
  SITE_TO_SITE_SPOKES = 2;
}

// The route's type
enum RouteType {
  // No route type information specified
  ROUTE_TYPE_UNSPECIFIED = 0;

  // The route leads to a destination within the primary address range of the
  // VPC network's subnet.
  VPC_PRIMARY_SUBNET = 1;

  // The route leads to a destination within the secondary address range of the
  // VPC network's subnet.
  VPC_SECONDARY_SUBNET = 2;

  // The route leads to a destination in a dynamic route. Dynamic routes are
  // derived from Border Gateway Protocol (BGP) advertisements received from an
  // NCC hybrid spoke.
  DYNAMIC_ROUTE = 3;
}

// The State enum represents the lifecycle stage of a Network Connectivity
// Center resource.
enum State {
  // No state information available
  STATE_UNSPECIFIED = 0;

  // The resource's create operation is in progress.
  CREATING = 1;

  // The resource is active
  ACTIVE = 2;

  // The resource's delete operation is in progress.
  DELETING = 3;

  // The resource's accept operation is in progress.
  ACCEPTING = 8;

  // The resource's reject operation is in progress.
  REJECTING = 9;

  // The resource's update operation is in progress.
  UPDATING = 6;

  // The resource is inactive.
  INACTIVE = 7;

  // The hub associated with this spoke resource has been deleted.
  // This state applies to spoke resources only.
  OBSOLETE = 10;

  // The resource is in an undefined state due to resource creation or deletion
  // failure. You can try to delete the resource later or contact support for
  // help.
  FAILED = 11;
}

// The SpokeType enum represents the type of spoke. The type
// reflects the kind of resource that a spoke is associated with.
enum SpokeType {
  // Unspecified spoke type.
  SPOKE_TYPE_UNSPECIFIED = 0;

  // Spokes associated with VPN tunnels.
  VPN_TUNNEL = 1;

  // Spokes associated with VLAN attachments.
  INTERCONNECT_ATTACHMENT = 2;

  // Spokes associated with router appliance instances.
  ROUTER_APPLIANCE = 3;

  // Spokes associated with VPC networks.
  VPC_NETWORK = 4;

  // Spokes that are backed by a producer VPC network.
  PRODUCER_VPC_NETWORK = 7;
}

// This enum controls the policy mode used in a hub.
enum PolicyMode {
  // Policy mode is unspecified. It defaults to PRESET
  // with preset_topology = MESH.
  POLICY_MODE_UNSPECIFIED = 0;

  // Hub uses one of the preset topologies.
  PRESET = 1;
}

// The list of available preset topologies.
enum PresetTopology {
  // Preset topology is unspecified. When policy_mode = PRESET,
  // it defaults to MESH.
  PRESET_TOPOLOGY_UNSPECIFIED = 0;

  // Mesh topology is implemented. Group `default` is automatically created.
  // All spokes in the hub are added to group `default`.
  MESH = 2;

  // Star topology is implemented. Two groups, `center` and `edge`, are
  // automatically created along with hub creation. Spokes have to join one of
  // the groups during creation.
  STAR = 3;
}

// A Network Connectivity Center hub is a global management resource to which
// you attach spokes. A single hub can contain spokes from multiple regions.
// However, if any of a hub's spokes use the site-to-site data transfer feature,
// the resources associated with those spokes must all be in the same VPC
// network. Spokes that do not use site-to-site data transfer can be associated
// with any VPC network in your project.
message Hub {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/Hub"
    pattern: "projects/{project}/locations/global/hubs/{hub}"
  };

  // Immutable. The name of the hub. Hub names must be unique. They use the
  // following form:
  //     `projects/{project_number}/locations/global/hubs/{hub_id}`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time the hub was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time the hub was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional labels in key-value pair format. For more information about
  // labels, see [Requirements for
  // labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements).
  map<string, string> labels = 4;

  // Optional. An optional description of the hub.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The Google-generated UUID for the hub. This value is unique
  // across all hub resources. If a hub is deleted and another with the same
  // name is created, the new hub is assigned a different unique_id.
  string unique_id = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current lifecycle state of this hub.
  State state = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The VPC networks associated with this hub's spokes.
  //
  // This field is read-only. Network Connectivity Center automatically
  // populates it based on the set of spokes attached to the hub.
  repeated RoutingVPC routing_vpcs = 10;

  // Output only. The route tables that belong to this hub. They use the
  // following form:
  //    `projects/{project_number}/locations/global/hubs/{hub_id}/routeTables/{route_table_id}`
  //
  // This field is read-only. Network Connectivity Center automatically
  // populates it based on the route tables nested under the hub.
  repeated string route_tables = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A summary of the spokes associated with a hub. The
  // summary includes a count of spokes according to type
  // and according to state. If any spokes are inactive,
  // the summary also lists the reasons they are inactive,
  // including a count for each reason.
  SpokeSummary spoke_summary = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The policy mode of this hub. This field can be either
  // PRESET or CUSTOM. If unspecified, the
  // policy_mode defaults to PRESET.
  PolicyMode policy_mode = 13 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The topology implemented in this hub. Currently, this field is
  // only used when policy_mode = PRESET. The available preset topologies are
  // MESH and STAR. If preset_topology is unspecified and policy_mode = PRESET,
  // the preset_topology defaults to MESH. When policy_mode = CUSTOM,
  // the preset_topology is set to PRESET_TOPOLOGY_UNSPECIFIED.
  PresetTopology preset_topology = 14 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Whether Private Service Connect connection propagation is enabled
  // for the hub. If true, Private Service Connect endpoints in VPC spokes
  // attached to the hub are made accessible to other VPC spokes attached to the
  // hub. The default value is false.
  optional bool export_psc = 15 [(google.api.field_behavior) = OPTIONAL];
}

// RoutingVPC contains information about the VPC networks associated
// with the spokes of a Network Connectivity Center hub.
message RoutingVPC {
  // The URI of the VPC network.
  string uri = 1 [
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Output only. If true, indicates that this VPC network is currently
  // associated with spokes that use the data transfer feature (spokes where the
  // site_to_site_data_transfer field is set to true). If you create new spokes
  // that use data transfer, they must be associated with this VPC network. At
  // most, one VPC network will have this field set to true.
  bool required_for_new_site_to_site_data_transfer_spokes = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A Network Connectivity Center spoke represents one or more network
// connectivity resources.
//
// When you create a spoke, you associate it with a hub. You must also
// identify a value for exactly one of the following fields:
//
// * linked_vpn_tunnels
// * linked_interconnect_attachments
// * linked_router_appliance_instances
// * linked_vpc_network
message Spoke {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/Spoke"
    pattern: "projects/{project}/locations/{location}/spokes/{spoke}"
  };

  // The reason a spoke is inactive.
  message StateReason {
    // The Code enum represents the various reasons a state can be `INACTIVE`.
    enum Code {
      // No information available.
      CODE_UNSPECIFIED = 0;

      // The proposed spoke is pending review.
      PENDING_REVIEW = 1;

      // The proposed spoke has been rejected by the hub administrator.
      REJECTED = 2;

      // The spoke has been deactivated internally.
      PAUSED = 3;

      // Network Connectivity Center encountered errors while accepting
      // the spoke.
      FAILED = 4;

      // The proposed spoke update is pending review.
      UPDATE_PENDING_REVIEW = 5;

      // The proposed spoke update has been rejected by the hub administrator.
      UPDATE_REJECTED = 6;

      // Network Connectivity Center encountered errors while accepting
      // the spoke update.
      UPDATE_FAILED = 7;
    }

    // The code associated with this reason.
    Code code = 1;

    // Human-readable details about this reason.
    string message = 2;

    // Additional information provided by the user in the RejectSpoke call.
    string user_details = 3;
  }

  // Immutable. The name of the spoke. Spoke names must be unique. They use the
  // following form:
  //     `projects/{project_number}/locations/{region}/spokes/{spoke_id}`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time the spoke was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time the spoke was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional labels in key-value pair format. For more information about
  // labels, see [Requirements for
  // labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements).
  map<string, string> labels = 4;

  // Optional. An optional description of the spoke.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Immutable. The name of the hub that this spoke is attached to.
  string hub = 6 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Optional. The name of the group that this spoke is associated with.
  string group = 23 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Group"
    }
  ];

  // Optional. VPN tunnels that are associated with the spoke.
  LinkedVpnTunnels linked_vpn_tunnels = 17
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. VLAN attachments that are associated with the spoke.
  LinkedInterconnectAttachments linked_interconnect_attachments = 18
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Router appliance instances that are associated with the spoke.
  LinkedRouterApplianceInstances linked_router_appliance_instances = 19
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. VPC network that is associated with the spoke.
  LinkedVpcNetwork linked_vpc_network = 20
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The linked producer VPC that is associated with the spoke.
  LinkedProducerVpcNetwork linked_producer_vpc_network = 26
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. The Google-generated UUID for the spoke. This value is unique
  // across all spoke resources. If a spoke is deleted and another with the same
  // name is created, the new spoke is assigned a different `unique_id`.
  string unique_id = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current lifecycle state of this spoke.
  State state = 15 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The reasons for current state of the spoke.
  repeated StateReason reasons = 21 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The type of resource associated with the spoke.
  SpokeType spoke_type = 22 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. This checksum is computed by the server based on the value of
  // other fields, and may be sent on update and delete requests to ensure the
  // client has an up-to-date value before proceeding.
  string etag = 27 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The list of fields waiting for hub administration's approval.
  repeated string field_paths_pending_update = 28
      [(google.api.field_behavior) = OPTIONAL];
}

message RouteTable {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/RouteTable"
    pattern: "projects/{project}/locations/global/hubs/{hub}/routeTables/{route_table}"
  };

  // Immutable. The name of the route table. Route table names must be unique.
  // They use the following form:
  //      `projects/{project_number}/locations/global/hubs/{hub}/routeTables/{route_table_id}`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time the route table was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time the route table was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional labels in key-value pair format. For more information about
  // labels, see [Requirements for
  // labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements).
  map<string, string> labels = 4;

  // An optional description of the route table.
  string description = 5;

  // Output only. The Google-generated UUID for the route table. This value is
  // unique across all route table resources. If a route table is deleted and
  // another with the same name is created, the new route table is assigned
  // a different `uid`.
  string uid = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current lifecycle state of this route table.
  State state = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A route defines a path from VM instances within a spoke to a specific
// destination resource. Only VPC spokes have routes.
message Route {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/HubRoute"
    pattern: "projects/{project}/locations/global/hubs/{hub}/routeTables/{route_table}/routes/{route}"
  };

  // Immutable. The name of the route. Route names must be unique. Route names
  // use the following form:
  //      `projects/{project_number}/locations/global/hubs/{hub}/routeTables/{route_table_id}/routes/{route_id}`
  string name = 3 [(google.api.field_behavior) = IMMUTABLE];

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

  // Output only. The time the route was last updated.
  google.protobuf.Timestamp update_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The destination IP address range.
  string ip_cidr_range = 1;

  // Output only. The route's type. Its type is determined by the properties of
  // its IP address range.
  RouteType type = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. The destination VPC network for packets on this route.
  NextHopVpcNetwork next_hop_vpc_network = 2
      [(google.api.field_behavior) = IMMUTABLE];

  // Optional labels in key-value pair format. For more information about
  // labels, see [Requirements for
  // labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements).
  map<string, string> labels = 6;

  // An optional description of the route.
  string description = 7;

  // Output only. The Google-generated UUID for the route. This value is unique
  // across all Network Connectivity Center route resources. If a
  // route is deleted and another with the same name is created,
  // the new route is assigned a different `uid`.
  string uid = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current lifecycle state of the route.
  State state = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. The spoke that this route leads to.
  // Example: projects/12345/locations/global/spokes/SPOKE
  string spoke = 11 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Output only. The origin location of the route.
  // Uses the following form: "projects/{project}/locations/{location}"
  // Example: projects/1234/locations/us-central1
  string location = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The priority of this route. Priority is used to break ties in
  // cases where a destination matches more than one route. In these cases the
  // route with the lowest-numbered priority value wins.
  int64 priority = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. The next-hop VPN tunnel for packets on this route.
  NextHopVPNTunnel next_hop_vpn_tunnel = 14
      [(google.api.field_behavior) = IMMUTABLE];

  // Immutable. The next-hop Router appliance instance for packets on this
  // route.
  NextHopRouterApplianceInstance next_hop_router_appliance_instance = 15
      [(google.api.field_behavior) = IMMUTABLE];

  // Immutable. The next-hop VLAN attachment for packets on this route.
  NextHopInterconnectAttachment next_hop_interconnect_attachment = 16
      [(google.api.field_behavior) = IMMUTABLE];
}

// A group represents a subset of spokes attached to a hub.
message Group {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/Group"
    pattern: "projects/{project}/locations/global/hubs/{hub}/groups/{group}"
  };

  // Immutable. The name of the group. Group names must be unique. They
  // use the following form:
  //      `projects/{project_number}/locations/global/hubs/{hub}/groups/{group_id}`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time the group was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time the group was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Labels in key-value pair format. For more information about
  // labels, see [Requirements for
  // labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements).
  map<string, string> labels = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The description of the group.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The Google-generated UUID for the group. This value is unique
  // across all group resources. If a group is deleted and
  // another with the same name is created, the new route table is assigned
  // a different unique_id.
  string uid = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current lifecycle state of this group.
  State state = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The auto-accept setting for this group.
  AutoAccept auto_accept = 8 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The name of the route table that corresponds to this group.
  // They use the following form:
  // `projects/{project_number}/locations/global/hubs/{hub_id}/routeTables/{route_table_id}`
  string route_table = 9 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The auto-accept setting for a group controls whether
// proposed spokes are automatically attached to the hub. If auto-accept is
// enabled, the spoke immediately is attached to the hub and becomes part of the
// group. In this case, the new spoke is in the ACTIVE state.
// If auto-accept is disabled, the spoke goes to the INACTIVE
// state, and it must be reviewed and accepted by a hub
// administrator.
message AutoAccept {
  // Optional. A list of project ids or project numbers for which you want
  // to enable auto-accept. The auto-accept setting is applied to
  // spokes being created or updated in these projects.
  repeated string auto_accept_projects = 1
      [(google.api.field_behavior) = OPTIONAL];
}

// Request for
// [HubService.ListHubs][google.cloud.networkconnectivity.v1.HubService.ListHubs]
// method.
message ListHubsRequest {
  // 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 to return.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the list of results.
  string filter = 4;

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

// Response for
// [HubService.ListHubs][google.cloud.networkconnectivity.v1.HubService.ListHubs]
// method.
message ListHubsResponse {
  // The requested hubs.
  repeated Hub hubs = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// Request for
// [HubService.GetHub][google.cloud.networkconnectivity.v1.HubService.GetHub]
// method.
message GetHubRequest {
  // Required. The name of the hub resource to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];
}

// Request for
// [HubService.CreateHub][google.cloud.networkconnectivity.v1.HubService.CreateHub]
// method.
message CreateHubRequest {
  // Required. The parent resource.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. A unique identifier for the hub.
  string hub_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The initial values for a new hub.
  Hub hub = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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
// [HubService.UpdateHub][google.cloud.networkconnectivity.v1.HubService.UpdateHub]
// method.
message UpdateHubRequest {
  // Optional. In the case of an update to an existing hub, field mask is used
  // to specify the fields to be overwritten. The fields specified in the
  // update_mask are relative to the resource, not the full request. A field is
  // overwritten if it is in the mask. If the user does not provide a mask, then
  // all fields are overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The state that the hub should be in after the update.
  Hub hub = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The request for
// [HubService.DeleteHub][google.cloud.networkconnectivity.v1.HubService.DeleteHub].
message DeleteHubRequest {
  // Required. The name of the hub to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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];
}

// The request for
// [HubService.ListHubSpokes][google.cloud.networkconnectivity.v1.HubService.ListHubSpokes].
//
message ListHubSpokesRequest {
  // Enum that controls which spoke fields are included in the response.
  enum SpokeView {
    // The spoke view is unspecified. When the spoke view is unspecified, the
    // API returns the same fields as the `BASIC` view.
    SPOKE_VIEW_UNSPECIFIED = 0;

    // Includes `name`, `create_time`, `hub`, `unique_id`, `state`, `reasons`,
    // and `spoke_type`. This is the default value.
    BASIC = 1;

    // Includes all spoke fields except `labels`.
    // You can use the `DETAILED` view only when you set the `spoke_locations`
    // field to `[global]`.
    DETAILED = 2;
  }

  // Required. The name of the hub.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // A list of locations.
  // Specify one of the following: `[global]`, a single region (for
  // example, `[us-central1]`), or a combination of
  // values (for example, `[global, us-central1, us-west1]`).
  // If the spoke_locations field is populated, the list of results
  // includes only spokes in the specified location.
  // If the spoke_locations field is not populated, the list of results
  // includes spokes in all locations.
  repeated string spoke_locations = 2;

  // The maximum number of results to return per page.
  int32 page_size = 3;

  // The page token.
  string page_token = 4;

  // An expression that filters the list of results.
  string filter = 5;

  // Sort the results by name or create_time.
  string order_by = 6;

  // The view of the spoke to return.
  // The view that you use determines which spoke fields are included in the
  // response.
  SpokeView view = 7;
}

// The response for
// [HubService.ListHubSpokes][google.cloud.networkconnectivity.v1.HubService.ListHubSpokes].
message ListHubSpokesResponse {
  // The requested spokes.
  // The spoke fields can be partially populated based on the `view` field in
  // the request message.
  repeated Spoke spokes = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// The request for
// [HubService.QueryHubStatus][google.cloud.networkconnectivity.v1.HubService.QueryHubStatus].
message QueryHubStatusRequest {
  // Required. The name of the hub.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Optional. The maximum number of results to return per page.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. An expression that filters the list of results.
  // The filter can be used to filter the results by the following fields:
  //   * `psc_propagation_status.source_spoke`
  //   * `psc_propagation_status.source_group`
  //   * `psc_propagation_status.source_forwarding_rule`
  //   * `psc_propagation_status.target_spoke`
  //   * `psc_propagation_status.target_group`
  //   * `psc_propagation_status.code`
  //   * `psc_propagation_status.message`
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Sort the results in ascending order by the specified fields.
  // A comma-separated list of any of these fields:
  //   * `psc_propagation_status.source_spoke`
  //   * `psc_propagation_status.source_group`
  //   * `psc_propagation_status.source_forwarding_rule`
  //   * `psc_propagation_status.target_spoke`
  //   * `psc_propagation_status.target_group`
  //   * `psc_propagation_status.code`
  // If `group_by` is set, the value of the `order_by` field must be the
  // same as or a subset of the `group_by` field.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Aggregate the results by the specified fields.
  // A comma-separated list of any of these fields:
  //   * `psc_propagation_status.source_spoke`
  //   * `psc_propagation_status.source_group`
  //   * `psc_propagation_status.source_forwarding_rule`
  //   * `psc_propagation_status.target_spoke`
  //   * `psc_propagation_status.target_group`
  //   * `psc_propagation_status.code`
  string group_by = 6 [(google.api.field_behavior) = OPTIONAL];
}

// The response for
// [HubService.QueryHubStatus][google.cloud.networkconnectivity.v1.HubService.QueryHubStatus].
message QueryHubStatusResponse {
  // The list of hub status.
  repeated HubStatusEntry hub_status_entries = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;
}

// A hub status entry represents the status of a set of propagated Private
// Service Connect connections grouped by certain fields.
message HubStatusEntry {
  // The number of propagated Private Service Connect connections with this
  // status. If the `group_by` field was not set in the request message, the
  // value of this field is 1.
  int32 count = 1;

  // The fields that this entry is grouped by. This has the same value as the
  // `group_by` field in the request message.
  string group_by = 2;

  // The Private Service Connect propagation status.
  PscPropagationStatus psc_propagation_status = 3;
}

// The status of one or more propagated Private Service Connect connections in a
// hub.
message PscPropagationStatus {
  // The Code enum represents the state of the Private Service Connect
  // propagation.
  enum Code {
    // The code is unspecified.
    CODE_UNSPECIFIED = 0;

    // The propagated Private Service Connect connection is ready.
    READY = 1;

    // The Private Service Connect connection is propagating. This is a
    // transient state.
    PROPAGATING = 2;

    // The Private Service Connect connection propagation failed because the VPC
    // network or the project of the target spoke has exceeded the connection
    // limit set by the producer.
    ERROR_PRODUCER_PROPAGATED_CONNECTION_LIMIT_EXCEEDED = 3;

    // The Private Service Connect connection propagation failed because the NAT
    // IP subnet space has been exhausted. It is equivalent to the `Needs
    // attention` status of the Private Service Connect connection. See
    // https://cloud.google.com/vpc/docs/about-accessing-vpc-hosted-services-endpoints#connection-statuses.
    ERROR_PRODUCER_NAT_IP_SPACE_EXHAUSTED = 4;

    // The Private Service Connect connection propagation failed because the
    // `PSC_ILB_CONSUMER_FORWARDING_RULES_PER_PRODUCER_NETWORK` quota in the
    // producer VPC network has been exceeded.
    ERROR_PRODUCER_QUOTA_EXCEEDED = 5;

    // The Private Service Connect connection propagation failed because the
    // `PSC_PROPAGATED_CONNECTIONS_PER_VPC_NETWORK` quota in the consumer
    // VPC network has been exceeded.
    ERROR_CONSUMER_QUOTA_EXCEEDED = 6;
  }

  // The name of the spoke that the source forwarding rule belongs to.
  string source_spoke = 1;

  // The name of the group that the source spoke belongs to.
  string source_group = 2;

  // The name of the forwarding rule exported to the hub.
  string source_forwarding_rule = 3;

  // The name of the spoke that the source forwarding rule propagates to.
  string target_spoke = 4;

  // The name of the group that the target spoke belongs to.
  string target_group = 5;

  // The propagation status.
  Code code = 6;

  // The human-readable summary of the Private Service Connect connection
  // propagation status.
  string message = 7;
}

// The request for
// [HubService.ListSpokes][google.cloud.networkconnectivity.v1.HubService.ListSpokes].
message ListSpokesRequest {
  // Required. The parent resource.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // The maximum number of results to return per page.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the list of results.
  string filter = 4;

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

// The response for
// [HubService.ListSpokes][google.cloud.networkconnectivity.v1.HubService.ListSpokes].
message ListSpokesResponse {
  // The requested spokes.
  repeated Spoke spokes = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// The request for
// [HubService.GetSpoke][google.cloud.networkconnectivity.v1.HubService.GetSpoke].
message GetSpokeRequest {
  // Required. The name of the spoke resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];
}

// The request for
// [HubService.CreateSpoke][google.cloud.networkconnectivity.v1.HubService.CreateSpoke].
message CreateSpokeRequest {
  // Required. The parent resource.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. Unique id for the spoke to create.
  string spoke_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The initial values for a new spoke.
  Spoke spoke = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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
// [HubService.UpdateSpoke][google.cloud.networkconnectivity.v1.HubService.UpdateSpoke]
// method.
message UpdateSpokeRequest {
  // Optional. In the case of an update to an existing spoke, field mask is used
  // to specify the fields to be overwritten. The fields specified in the
  // update_mask are relative to the resource, not the full request. A field is
  // overwritten if it is in the mask. If the user does not provide a mask, then
  // all fields are overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The state that the spoke should be in after the update.
  Spoke spoke = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The request for
// [HubService.DeleteSpoke][google.cloud.networkconnectivity.v1.HubService.DeleteSpoke].
message DeleteSpokeRequest {
  // Required. The name of the spoke to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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];
}

// The request for
// [HubService.AcceptHubSpoke][google.cloud.networkconnectivity.v1.HubService.AcceptHubSpoke].
message AcceptHubSpokeRequest {
  // Required. The name of the hub into which to accept the spoke.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Required. The URI of the spoke to accept into the hub.
  string spoke_uri = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The response for
// [HubService.AcceptHubSpoke][google.cloud.networkconnectivity.v1.HubService.AcceptHubSpoke].
message AcceptHubSpokeResponse {
  // The spoke that was operated on.
  Spoke spoke = 1;
}

// The request for
// [HubService.RejectHubSpoke][google.cloud.networkconnectivity.v1.HubService.RejectHubSpoke].
message RejectHubSpokeRequest {
  // Required. The name of the hub from which to reject the spoke.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Required. The URI of the spoke to reject from the hub.
  string spoke_uri = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information provided by the hub administrator.
  string details = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The response for
// [HubService.RejectHubSpoke][google.cloud.networkconnectivity.v1.HubService.RejectHubSpoke].
message RejectHubSpokeResponse {
  // The spoke that was operated on.
  Spoke spoke = 1;
}

// The request for
// [HubService.AcceptSpokeUpdate][google.cloud.networkconnectivity.v1.HubService.AcceptSpokeUpdate].
message AcceptSpokeUpdateRequest {
  // Required. The name of the hub to accept spoke update.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Required. The URI of the spoke to accept update.
  string spoke_uri = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Required. The etag of the spoke to accept update.
  string spoke_etag = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// The response for
// [HubService.AcceptSpokeUpdate][google.cloud.networkconnectivity.v1.HubService.AcceptSpokeUpdate].
message AcceptSpokeUpdateResponse {
  // The spoke that was operated on.
  Spoke spoke = 1;
}

// The request for
// [HubService.RejectSpokeUpdate][google.cloud.networkconnectivity.v1.HubService.RejectSpokeUpdate].
message RejectSpokeUpdateRequest {
  // Required. The name of the hub to reject spoke update.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // Required. The URI of the spoke to reject update.
  string spoke_uri = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Required. The etag of the spoke to reject update.
  string spoke_etag = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. Additional information provided by the hub administrator.
  string details = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 5 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// The response for
// [HubService.RejectSpokeUpdate][google.cloud.networkconnectivity.v1.HubService.RejectSpokeUpdate].
message RejectSpokeUpdateResponse {
  // The spoke that was operated on.
  Spoke spoke = 1;
}

// The request for
// [HubService.GetRouteTable][google.cloud.networkconnectivity.v1.HubService.GetRouteTable].
message GetRouteTableRequest {
  // Required. The name of the route table resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/RouteTable"
    }
  ];
}

// The request for
// [HubService.GetRoute][google.cloud.networkconnectivity.v1.HubService.GetRoute].
message GetRouteRequest {
  // Required. The name of the route resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/HubRoute"
    }
  ];
}

// Request for
// [HubService.ListRoutes][google.cloud.networkconnectivity.v1.HubService.ListRoutes]
// method.
message ListRoutesRequest {
  // Required. The parent resource's name.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/RouteTable"
    }
  ];

  // The maximum number of results to return per page.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the list of results.
  string filter = 4;

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

// Response for
// [HubService.ListRoutes][google.cloud.networkconnectivity.v1.HubService.ListRoutes]
// method.
message ListRoutesResponse {
  // The requested routes.
  repeated Route routes = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// Request for
// [HubService.ListRouteTables][google.cloud.networkconnectivity.v1.HubService.ListRouteTables]
// method.
message ListRouteTablesRequest {
  // Required. The parent resource's name.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // The maximum number of results to return per page.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the list of results.
  string filter = 4;

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

// Response for
// [HubService.ListRouteTables][google.cloud.networkconnectivity.v1.HubService.ListRouteTables]
// method.
message ListRouteTablesResponse {
  // The requested route tables.
  repeated RouteTable route_tables = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// Request for
// [HubService.ListGroups][google.cloud.networkconnectivity.v1.HubService.ListGroups]
// method.
message ListGroupsRequest {
  // Required. The parent resource's name.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Hub"
    }
  ];

  // The maximum number of results to return per page.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the list of results.
  string filter = 4;

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

// Response for
// [HubService.ListGroups][google.cloud.networkconnectivity.v1.HubService.ListGroups]
// method.
message ListGroupsResponse {
  // The requested groups.
  repeated Group groups = 1;

  // The token for the next page of the response. To see more results,
  // use this value as the page_token for your next request. If this value
  // is empty, there are no more results.
  string next_page_token = 2;

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

// A collection of Cloud VPN tunnel resources. These resources should be
// redundant HA VPN tunnels that all advertise the same prefixes to Google
// Cloud. Alternatively, in a passive/active configuration, all tunnels
// should be capable of advertising the same prefixes.
message LinkedVpnTunnels {
  // The URIs of linked VPN tunnel resources.
  repeated string uris = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/VpnTunnel"
  }];

  // A value that controls whether site-to-site data transfer is enabled for
  // these resources. Data transfer is available only in [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 2;

  // Output only. The VPC network where these VPN tunnels are located.
  string vpc_network = 3 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Optional. IP ranges allowed to be included during import from hub (does not
  // control transit connectivity). The only allowed value for now is
  // "ALL_IPV4_RANGES".
  repeated string include_import_ranges = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// A collection of VLAN attachment resources. These resources should
// be redundant attachments that all advertise the same prefixes to Google
// Cloud. Alternatively, in active/passive configurations, all attachments
// should be capable of advertising the same prefixes.
message LinkedInterconnectAttachments {
  // The URIs of linked interconnect attachment resources
  repeated string uris = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/InterconnectAttachment"
  }];

  // A value that controls whether site-to-site data transfer is enabled for
  // these resources. Data transfer is available only in [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 2;

  // Output only. The VPC network where these VLAN attachments are located.
  string vpc_network = 3 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Optional. IP ranges allowed to be included during import from hub (does not
  // control transit connectivity). The only allowed value for now is
  // "ALL_IPV4_RANGES".
  repeated string include_import_ranges = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// A collection of router appliance instances. If you configure multiple router
// appliance instances to receive data from the same set of sites outside of
// Google Cloud, we recommend that you associate those instances with the same
// spoke.
message LinkedRouterApplianceInstances {
  // The list of router appliance instances.
  repeated RouterApplianceInstance instances = 1;

  // A value that controls whether site-to-site data transfer is enabled for
  // these resources. Data transfer is available only in [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 2;

  // Output only. The VPC network where these router appliance instances are
  // located.
  string vpc_network = 3 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Optional. IP ranges allowed to be included during import from hub (does not
  // control transit connectivity). The only allowed value for now is
  // "ALL_IPV4_RANGES".
  repeated string include_import_ranges = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// An existing VPC network.
message LinkedVpcNetwork {
  // Required. The URI of the VPC network resource.
  string uri = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Optional. IP ranges encompassing the subnets to be excluded from peering.
  repeated string exclude_export_ranges = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. IP ranges allowed to be included from peering.
  repeated string include_export_ranges = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The proposed include export IP ranges waiting for hub
  // administration's approval.
  repeated string proposed_include_export_ranges = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. The proposed exclude export IP ranges waiting for hub
  // administration's approval.
  repeated string proposed_exclude_export_ranges = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The list of Producer VPC spokes that this VPC spoke is a
  // service consumer VPC spoke for. These producer VPCs are connected through
  // VPC peering to this spoke's backing VPC network. Because they are directly
  // connected throuh VPC peering, NCC export filters do not apply between the
  // service consumer VPC spoke and any of its producer VPC spokes. This VPC
  // spoke cannot be deleted as long as any of these producer VPC spokes are
  // connected to the NCC Hub.
  repeated string producer_vpc_spokes = 4 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];
}

message LinkedProducerVpcNetwork {
  // Immutable. The URI of the Service Consumer VPC that the Producer VPC is
  // peered with.
  string network = 1 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Output only. The Service Consumer Network spoke.
  string service_consumer_vpc_spoke = 6 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Spoke"
    }
  ];

  // Immutable. The name of the VPC peering between the Service Consumer VPC and
  // the Producer VPC (defined in the Tenant project) which is added to the NCC
  // hub. This peering must be in ACTIVE state.
  string peering = 2 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The URI of the Producer VPC.
  string producer_network = 5 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Optional. IP ranges encompassing the subnets to be excluded from peering.
  repeated string exclude_export_ranges = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. IP ranges allowed to be included from peering.
  repeated string include_export_ranges = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The proposed include export IP ranges waiting for hub
  // administration's approval.
  repeated string proposed_include_export_ranges = 7
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. The proposed exclude export IP ranges waiting for hub
  // administration's approval.
  repeated string proposed_exclude_export_ranges = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A router appliance instance is a Compute Engine virtual machine (VM) instance
// that acts as a BGP speaker. A router appliance instance is specified by the
// URI of the VM and the internal IP address of one of the VM's network
// interfaces.
message RouterApplianceInstance {
  // The URI of the VM.
  string virtual_machine = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/Instance"
  }];

  // The IP address on the VM to use for peering.
  string ip_address = 3;
}

// Metadata about locations
message LocationMetadata {
  // List of supported features
  repeated LocationFeature location_features = 1;
}

message NextHopVpcNetwork {
  // The URI of the VPC network resource
  string uri = 1 [
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];
}

// A route next hop that leads to a VPN tunnel resource.
message NextHopVPNTunnel {
  // The URI of the VPN tunnel resource.
  string uri = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/VpnTunnel"
  }];

  // The VPC network where this VPN tunnel is located.
  string vpc_network = 2 [
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Indicates whether site-to-site data transfer is allowed for this VPN tunnel
  // resource. Data transfer is available only in [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 3;
}

// A route next hop that leads to a Router appliance instance.
message NextHopRouterApplianceInstance {
  // The URI of the Router appliance instance.
  string uri = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/Instance"
  }];

  // The VPC network where this VM is located.
  string vpc_network = 2 [
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Indicates whether site-to-site data transfer is allowed for this Router
  // appliance instance resource. Data transfer is available only in [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 3;
}

// A route next hop that leads to an interconnect attachment resource.
message NextHopInterconnectAttachment {
  // The URI of the interconnect attachment resource.
  string uri = 1 [(google.api.resource_reference) = {
    type: "compute.googleapis.com/InterconnectAttachment"
  }];

  // The VPC network where this interconnect attachment is located.
  string vpc_network = 2 [
    (google.api.resource_reference) = { type: "compute.googleapis.com/Network" }
  ];

  // Indicates whether site-to-site data transfer is allowed for this
  // interconnect attachment resource. Data transfer is available only in
  // [supported
  // locations](https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/locations).
  bool site_to_site_data_transfer = 3;
}

// Summarizes information about the spokes associated with a hub.
// The summary includes a count of spokes according to type
// and according to state. If any spokes are inactive,
// the summary also lists the reasons they are inactive,
// including a count for each reason.
message SpokeSummary {
  // The number of spokes of a given type that are associated
  // with a specific hub. The type indicates what kind of
  // resource is associated with the spoke.
  message SpokeTypeCount {
    // Output only. The type of the spokes.
    SpokeType spoke_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of spokes of this type that are
    // associated with the hub.
    int64 count = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The number of spokes that are in a particular state
  // and associated with a given hub.
  message SpokeStateCount {
    // Output only. The state of the spokes.
    State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of spokes that are in this state
    // and associated with a given hub.
    int64 count = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The number of spokes in the hub that are inactive for this reason.
  message SpokeStateReasonCount {
    // Output only. The reason that a spoke is inactive.
    Spoke.StateReason.Code state_reason_code = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The total number of spokes that are inactive for a
    // particular reason and associated with a given hub.
    int64 count = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Counts the number of spokes of each type that are
  // associated with a specific hub.
  repeated SpokeTypeCount spoke_type_counts = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Counts the number of spokes that are in each state
  // and associated with a given hub.
  repeated SpokeStateCount spoke_state_counts = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Counts the number of spokes that are inactive for each
  // possible reason and associated with a given hub.
  repeated SpokeStateReasonCount spoke_state_reason_counts = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The request for
// [HubService.GetGroup][google.cloud.networkconnectivity.v1.HubService.GetGroup].
message GetGroupRequest {
  // Required. The name of the route table resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "networkconnectivity.googleapis.com/Group"
    }
  ];
}

// Request for
// [HubService.UpdateGroup][google.cloud.networkconnectivity.v1.HubService.UpdateGroup]
// method.
message UpdateGroupRequest {
  // Optional. In the case of an update to an existing group, field mask is used
  // to specify the fields to be overwritten. The fields specified in the
  // update_mask are relative to the resource, not the full request. A field is
  // overwritten if it is in the mask. If the user does not provide a mask, then
  // all fields are overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The state that the group should be in after the update.
  Group group = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID to identify requests. Specify a unique request ID so
  // that if you must retry your request, the server knows to ignore the request
  // if it has already been completed. The server guarantees that a request
  // doesn't result in creation of duplicate commitments for at least 60
  // minutes.
  //
  // 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 to see whether the original operation
  // was received. If it was, the server ignores the second request. This
  // behavior prevents clients from mistakenly 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 = 3 [(google.api.field_behavior) = OPTIONAL];
}
