// Copyright 2022 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/longrunning/operations.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 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"
    };
  }

  // 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"
    };
  }
}

// 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 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 Update operation is in progress
  UPDATING = 6;
}

// A Network Connectivity Center hub is a collection of spokes. A single hub
// can contain spokes from multiple regions. However, if any of a hub's spokes
// use the data transfer feature, the resources associated with those spokes
// must all reside in the same VPC network. Spokes that do not use 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 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 hub.
  string description = 5;

  // 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;
}

// 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 a connection between your
// Google Cloud network resources and a non-Google-Cloud network.
//
// 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
message Spoke {
  option (google.api.resource) = {
    type: "networkconnectivity.googleapis.com/Spoke"
    pattern: "projects/{project}/locations/{location}/spokes/{spoke}"
  };

  // 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 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 spoke.
  string description = 5;

  // 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"
    }
  ];

  // VPN tunnels that are associated with the spoke.
  LinkedVpnTunnels linked_vpn_tunnels = 17;

  // VLAN attachments that are associated with the spoke.
  LinkedInterconnectAttachments linked_interconnect_attachments = 18;

  // Router appliance instances that are associated with the spoke.
  LinkedRouterApplianceInstances linked_router_appliance_instances = 19;

  // 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];
}

// 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 that should be returned.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An 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
// [HubService.ListHubs][google.cloud.networkconnectivity.v1.HubService.ListHubs]
// method.
message ListHubsResponse {
  // The requested hubs.
  repeated Hub hubs = 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
// [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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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.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 per page that should be returned.
  int32 page_size = 2;

  // The page token.
  string page_token = 3;

  // An expression that filters the results listed in the response.
  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 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;
}

// 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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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 unique request ID (optional). If you specify this ID, you can
  // use it in cases when you need to retry your request. When you need to
  // retry, this ID lets the server know that it can ignore the request if it
  // has already been completed. The server guarantees 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 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];
}

// 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" }
  ];
}

// 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" }
  ];
}

// 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" }
  ];
}

// 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;
}
