// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.edgenetwork.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.EdgeNetwork.V1";
option go_package = "cloud.google.com/go/edgenetwork/apiv1/edgenetworkpb;edgenetworkpb";
option java_multiple_files = true;
option java_outer_classname = "ResourcesProto";
option java_package = "com.google.cloud.edgenetwork.v1";
option php_namespace = "Google\\Cloud\\EdgeNetwork\\V1";
option ruby_package = "Google::Cloud::EdgeNetwork::V1";

// ResourceState describes the state the resource.
// A normal lifecycle of a new resource being created would be: PENDING ->
// PROVISIONING -> RUNNING. A normal lifecycle of an existing resource being
// deleted would be: RUNNING -> DELETING. Any failures during processing will
// result the resource to be in a SUSPENDED state.
enum ResourceState {
  // Unspecified state.
  STATE_UNKNOWN = 0;

  // The resource is being prepared to be applied to the rack.
  STATE_PENDING = 1;

  // The resource has started being applied to the rack.
  STATE_PROVISIONING = 2;

  // The resource has been pushed to the rack.
  STATE_RUNNING = 3;

  // The resource failed to push to the rack.
  STATE_SUSPENDED = 4;

  // The resource is under deletion.
  STATE_DELETING = 5;
}

// A Google Edge Cloud zone.
message Zone {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/Zone"
    pattern: "projects/{project}/locations/{location}/zones/{zone}"
  };

  // Required. The resource name of the zone.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Deprecated: not implemented.
  // Labels as key value pairs.
  map<string, string> labels = 4 [deprecated = true];

  // Deprecated: not implemented.
  // The deployment layout type.
  string layout_name = 5 [deprecated = true];
}

// Message describing Network object
message Network {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/Network"
    pattern: "projects/{project}/locations/{location}/zones/{zone}/networks/{network}"
  };

  // Required. The canonical resource name of the network.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // IP (L3) MTU value of the network.
  // Valid values are: 1500 and 9000.
  // Default to 1500 if not set.
  int32 mtu = 6;
}

// Message describing Subnet object
message Subnet {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/Subnet"
    pattern: "projects/{project}/locations/{location}/zones/{zone}/subnets/{subnet}"
  };

  // Bonding type in the subnet.
  enum BondingType {
    // Unspecified
    // Bonding type will be unspecified by default and if the user chooses to
    // not specify a bonding type at time of creating the VLAN. This will be
    // treated as mixed bonding where the VLAN will have both bonded and
    // non-bonded connectivity to machines.
    BONDING_TYPE_UNSPECIFIED = 0;

    // Multi homed.
    BONDED = 1;

    // Single homed.
    NON_BONDED = 2;
  }

  // Required. The canonical resource name of the subnet.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. The network that this subnetwork belongs to.
  string network = 6 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgenetwork.googleapis.com/Network"
    }
  ];

  // The ranges of ipv4 addresses that are owned by this subnetwork.
  repeated string ipv4_cidr = 7;

  // The ranges of ipv6 addresses that are owned by this subnetwork.
  repeated string ipv6_cidr = 8;

  // Optional. VLAN id provided by user. If not specified we assign one
  // automatically.
  int32 vlan_id = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A bonding type in the subnet creation specifies whether a VLAN
  // being created will be present on Bonded or Non-Bonded or Both port types.
  // In addition, this flag is to be used to set the specific network
  // configuration which clusters can then use for their workloads based on the
  // bonding choice.
  BondingType bonding_type = 11 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Current stage of the resource to the device by config push.
  ResourceState state = 10 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Message describing Interconnect object
message Interconnect {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/Interconnect"
    pattern: "projects/{project}/locations/{location}/zones/{zone}/interconnects/{interconnect}"
  };

  // Type of interconnect.
  enum InterconnectType {
    // Unspecified.
    INTERCONNECT_TYPE_UNSPECIFIED = 0;

    // Dedicated Interconnect.
    DEDICATED = 1;
  }

  // Required. The canonical resource name of the interconnect.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Type of interconnect, which takes only the value 'DEDICATED' for
  // now.
  InterconnectType interconnect_type = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. Unique identifier for the link.
  string uuid = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Cloud resource name of the switch device.
  string device_cloud_resource_name = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Physical ports (e.g., TenGigE0/0/0/1) that form the
  // interconnect.
  repeated string physical_ports = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Message describing InterconnectAttachment object
message InterconnectAttachment {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/InterconnectAttachment"
    pattern: "projects/{project}/locations/{location}/zones/{zone}/interconnectAttachments/{interconnect_attachment}"
  };

  // Required. The canonical resource name of the interconnect attachment.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. The canonical name of underlying Interconnect object that this
  // attachment's traffic will traverse through. The name is in the form of
  // `projects/{project}/locations/{location}/zones/{zone}/interconnects/{interconnect}`.
  string interconnect = 6 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgenetwork.googleapis.com/Interconnect"
    }
  ];

  // Optional. The canonical Network name in the form of
  // `projects/{project}/locations/{location}/zones/{zone}/networks/{network}`.
  string network = 11 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "edgenetwork.googleapis.com/Network"
    }
  ];

  // Required. VLAN id provided by user. Must be site-wise unique.
  int32 vlan_id = 8 [(google.api.field_behavior) = REQUIRED];

  // IP (L3) MTU value of the virtual edge cloud.
  // Valid values are: 1500 and 9000.
  // Default to 1500 if not set.
  int32 mtu = 9;

  // Output only. Current stage of the resource to the device by config push.
  ResourceState state = 10 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Message describing Router object
message Router {
  option (google.api.resource) = {
    type: "edgenetwork.googleapis.com/Router"
    pattern: "projects/{project}/locations/{location}/zones/{zone}/routers/{router}"
  };

  // Router Interface defines the GDCE zone side layer-3 information for
  // building the BGP session.
  message Interface {
    // Name of this interface entry. Unique within the Zones resource.
    string name = 1;

    // IP address and range of the interface.
    string ipv4_cidr = 3;

    // IPv6 address and range of the interface.
    string ipv6_cidr = 6;

    // The canonical name of the linked Interconnect attachment.
    string linked_interconnect_attachment = 2;

    // The canonical name of the subnetwork resource that this interface
    // belongs to.
    string subnetwork = 4;

    // Create loopback interface in the router when specified.
    // The number of IP addresses must match the number of TOR devices.
    repeated string loopback_ip_addresses = 5;
  }

  // BGPPeer defines the peer side layer-3 information for building the BGP
  // session.
  message BgpPeer {
    // Name of this BGP peer. Unique within the Zones resource.
    string name = 1;

    // Name of the RouterInterface the BGP peer is associated with.
    string interface = 2;

    // IP range of the interface within Google.
    string interface_ipv4_cidr = 3;

    // IPv6 range of the interface within Google.
    string interface_ipv6_cidr = 7;

    // IP range of the BGP interface outside Google.
    string peer_ipv4_cidr = 4;

    // IPv6 range of the BGP interface outside Google.
    string peer_ipv6_cidr = 6;

    // Peer BGP Autonomous System Number (ASN). Each BGP interface may use
    // a different value.
    uint32 peer_asn = 5;

    // Output only. Local BGP Autonomous System Number (ASN).
    // This field is ST_NOT_REQUIRED because it stores private ASNs, which are
    // meaningless outside the zone in which they are being used.
    uint32 local_asn = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // BGP information specific to this router.
  message Bgp {
    // Locally assigned BGP ASN.
    uint32 asn = 1;

    // The interval in seconds between BGP keepalive messages that are
    // sent to the peer. Default is 20 with value between 20 and 60.
    uint32 keepalive_interval_in_seconds = 2;
  }

  // Required. The canonical resource name of the router.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

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

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

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. A free-text description of the resource. Max length 1024
  // characters.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. The canonical name of the network to which this router belongs.
  // The name is in the form of
  // `projects/{project}/locations/{location}/zones/{zone}/networks/{network}`.
  string network = 6 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgenetwork.googleapis.com/Network"
    }
  ];

  // Router interfaces.
  repeated Interface interface = 7;

  // BGP peers.
  repeated BgpPeer bgp_peer = 8;

  // BGP information specific to this router.
  Bgp bgp = 9;

  // Output only. Current stage of the resource to the device by config push.
  ResourceState state = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. A list of CIDRs in IP/Length format to advertise northbound as
  // static routes from this router.
  repeated string route_advertisements = 11
      [(google.api.field_behavior) = OPTIONAL];
}

// LinkLayerAddress contains an IP address and corresponding link-layer address.
message LinkLayerAddress {
  // The MAC address of this neighbor.
  string mac_address = 1;

  // The IP address of this neighbor.
  string ip_address = 2;
}

// SubnetStatus contains detailed and current technical information about this
// subnet resource.
message SubnetStatus {
  // The name of CCFE subnet resource.
  string name = 1;

  // BVI MAC address.
  string mac_address = 2;

  // A list of LinkLayerAddress, describing the ip address and corresponding
  // link-layer address of the neighbors for this subnet.
  repeated LinkLayerAddress link_layer_addresses = 3;
}

// Diagnostics information about interconnect, contains detailed and current
// technical information about Google's side of the connection.
message InterconnectDiagnostics {
  // Describing the status for each link on the Interconnect.
  message LinkStatus {
    // The unique ID for this link assigned during turn up by Google.
    string circuit_id = 1;

    // Describing the state of a LACP link.
    LinkLACPStatus lacp_status = 2;

    // A list of LinkLLDPStatus objects, used to describe LLDP status of each
    // peer for each link on the Interconnect.
    repeated LinkLLDPStatus lldp_statuses = 3;

    // Packet counts specific statistics for this link.
    PacketCounts packet_counts = 4;
  }

  // Containing a collection of interface-related statistics objects.
  message PacketCounts {
    // The number of packets that are delivered.
    int64 inbound_unicast = 1;

    // The number of inbound packets that contained errors.
    int64 inbound_errors = 2;

    // The number of inbound packets that were chosen to be discarded even
    // though no errors had been detected to prevent their being deliverable.
    int64 inbound_discards = 3;

    // The total number of packets that are requested be transmitted.
    int64 outbound_unicast = 4;

    // The number of outbound packets that could not be transmitted because of
    // errors.
    int64 outbound_errors = 5;

    // The number of outbound packets that were chosen to be discarded even
    // though no errors had been detected to prevent their being transmitted.
    int64 outbound_discards = 6;
  }

  // Describing the status of a LACP link.
  message LinkLACPStatus {
    // State enum for LACP link.
    enum State {
      // The default state indicating state is in unknown state.
      UNKNOWN = 0;

      // The link is configured and active within the bundle.
      ACTIVE = 1;

      // The link is not configured within the bundle, this means the rest of
      // the object should be empty.
      DETACHED = 2;
    }

    // The state of a LACP link.
    State state = 1;

    // System ID of the port on Google's side of the LACP exchange.
    string google_system_id = 2;

    // System ID of the port on the neighbor's side of the LACP exchange.
    string neighbor_system_id = 3;

    // A true value indicates that the participant will allow the link to be
    // used as part of the aggregate.
    // A false value indicates the link should be used as an individual link.
    bool aggregatable = 4;

    // If true, the participant is collecting incoming frames on the link,
    // otherwise false
    bool collecting = 5;

    // When true, the participant is distributing outgoing frames; when false,
    // distribution is disabled
    bool distributing = 6;
  }

  // Describing a LLDP link.
  message LinkLLDPStatus {
    // The peer system's administratively assigned name.
    string peer_system_name = 1;

    // The textual description of the network entity of LLDP peer.
    string peer_system_description = 2;

    // The peer chassis component of the endpoint identifier associated with the
    // transmitting LLDP agent.
    string peer_chassis_id = 3;

    // The format and source of the peer chassis identifier string.
    string peer_chassis_id_type = 4;

    // The port component of the endpoint identifier associated with the
    // transmitting LLDP agent. If the specified port is an IEEE 802.3 Repeater
    // port, then this TLV is optional.
    string peer_port_id = 5;

    // The format and source of the peer port identifier string.
    string peer_port_id_type = 6;
  }

  // The MAC address of the Interconnect's bundle interface.
  string mac_address = 1;

  // A list of LinkLayerAddress, describing the ip address and corresponding
  // link-layer address of the neighbors for this interconnect.
  repeated LinkLayerAddress link_layer_addresses = 2;

  // A list of LinkStatus objects, used to describe the status for each link on
  // the Interconnect.
  repeated LinkStatus links = 3;
}

// Describing the current status of a router.
message RouterStatus {
  // Status of a BGP peer.
  message BgpPeerStatus {
    // Status of the BGP peer: {UP, DOWN}
    enum BgpStatus {
      // The default status indicating BGP session is in unknown state.
      UNKNOWN = 0;

      // The UP status indicating BGP session is established.
      UP = 1;

      // The DOWN state indicating BGP session is not established yet.
      DOWN = 2;
    }

    // Name of this BGP peer. Unique within the Routers resource.
    string name = 1;

    // IP address of the local BGP interface.
    string ip_address = 2;

    // IP address of the remote BGP interface.
    string peer_ip_address = 3;

    // The current status of BGP.
    BgpStatus status = 4;

    // BGP state as specified in RFC1771.
    string state = 5;

    // Time this session has been up.
    // Format:
    //  14 years, 51 weeks, 6 days, 23 hours, 59 minutes, 59 seconds
    string uptime = 6;

    // Time this session has been up, in seconds.
    int64 uptime_seconds = 7;

    // A collection of counts for prefixes.
    PrefixCounter prefix_counter = 8;
  }

  // PrefixCounter contains a collection of prefixes related counts.
  message PrefixCounter {
    // Number of prefixes advertised.
    int64 advertised = 1;

    // Number of prefixes denied.
    int64 denied = 2;

    // Number of prefixes received.
    int64 received = 3;

    // Number of prefixes sent.
    int64 sent = 4;

    // Number of prefixes suppressed.
    int64 suppressed = 5;

    // Number of prefixes withdrawn.
    int64 withdrawn = 6;
  }

  // The canonical name of the network to which this router belongs.
  string network = 1 [(google.api.resource_reference) = {
    type: "edgenetwork.googleapis.com/Network"
  }];

  // A list of BgpPeerStatus objects, describing all BGP peers related to this
  // router.
  repeated BgpPeerStatus bgp_peer_status = 2;
}
