// SPDX-License-Identifier: Apache-2.0
// Public IP pools, address allocation bound to VM NICs, reverse DNS and monthly traffic
// (decision L-127, docs/network/DESIGN.md section 11.2 to 11.5). Pools themselves are
// created and changed through REST (/v1/ip-pools); this service carries the calls a
// portal or the tenancy module makes per server.
syntax = "proto3";

package kyvernon.v1;

import "kyvernon/v1/common.proto";

// Public IP pools, their allocations and traffic.
service IpPoolService {
  // Every IP pool.
  rpc ListPools(Empty) returns (ListPoolsResponse);
  // The allocations of one pool.
  rpc ListAllocations(ListAllocationsRequest) returns (ListAllocationsResponse);
  // Allocates one IPv4 address (or a /64 with family "ipv6") and binds it to a VM NIC.
  rpc AllocateAddress(AllocateAddressRequest) returns (Allocation);
  // Returns an address or "prefix/64" to the pool (quarantine) and deletes its PTR record.
  rpc FreeAddress(FreeAddressRequest) returns (Empty);
  // Sets the PTR name of an allocated address; an empty name removes it.
  rpc SetPtr(SetPtrRequest) returns (Empty);
  // The server-create hook: primary IPv4 address and, when the pool has IPv6, a /64.
  rpc AllocateForServer(AllocateForServerRequest) returns (ServerAddresses);
  // The server-delete hook: every address of the VM back to its pool.
  rpc ReleaseForServer(ReleaseForServerRequest) returns (ReleaseForServerResponse);
  // Monthly traffic per VM and tenant.
  rpc GetTraffic(GetTrafficRequest) returns (TrafficReport);
}

// An IP pool with its counts.
message IpPool {
  // Id of the pool.
  string id = 1;
  // Name.
  string name = 2;
  // Id of the host-bridge network of the pool.
  string network = 3;
  // IPv4 prefix length of the subnet.
  uint32 prefix_len = 4;
  // "start-end" per range.
  repeated string ranges = 5;
  // IPv4 gateway.
  string gateway = 6;
  // DNS servers handed to the guests.
  repeated string dns_servers = 7;
  // "prefix/len", empty without IPv6.
  string ipv6_prefix = 8;
  // IPv4 addresses the pool can hand out.
  uint64 capacity = 9;
  // Addresses allocated.
  uint64 allocated = 10;
  // Addresses in quarantine after a release.
  uint64 quarantined = 11;
  // Addresses free now.
  uint64 free = 12;
  // Length of the IPv6 block per server (64 to 128); 0 without IPv6.
  uint32 ipv6_server_prefix_len = 13;
  // Explicit IPv4 addresses handed out besides the ranges.
  repeated string addresses = 14;
}

// The IP pools.
message ListPoolsResponse {
  // Every pool.
  repeated IpPool items = 1;
}

// Lists the allocations of a pool.
message ListAllocationsRequest {
  // Id of the pool.
  string pool_id = 1;
}

// An address of a pool and who has it.
message Allocation {
  // IPv4 address or "prefix/64".
  string address = 1;
  // "ipv4" or "ipv6".
  string family = 2;
  // "allocated" or "quarantined".
  string status = 3;
  // "primary" or "extra" (IPv4).
  string role = 4;
  // Id of the virtual machine.
  string vm_id = 5;
  // MAC address of the network adapter.
  string mac = 6;
  // Id of the tenant; empty without one.
  string tenant = 7;
  // Reverse DNS name; empty without one.
  string ptr = 8;
  // Time of the allocation, RFC 3339.
  string allocated_at = 9;
  // End of the quarantine of a released address, RFC 3339; empty otherwise.
  string quarantined_until = 10;
}

// The allocations.
message ListAllocationsResponse {
  // Allocations of the pool.
  repeated Allocation items = 1;
}

// Allocates an address.
message AllocateAddressRequest {
  // Id of the pool.
  string pool_id = 1;
  // Empty: reserved for the tenant, not bound.
  string vm_id = 2;
  // Empty: the VM's first NIC on the pool's network.
  string mac = 3;
  // Empty: the lowest free address.
  string address = 4;
  // "primary" (default) or "extra".
  string role = 5;
  // "ipv4" (default) or "ipv6".
  string family = 6;
  // Id of the tenant the address is for.
  string tenant = 7;
  // Free text kept with the allocation (an order number).
  string reference = 8;
}

// Releases an address.
message FreeAddressRequest {
  // Id of the pool.
  string pool_id = 1;
  // The address, or the IPv6 block as `prefix/64`.
  string address = 2;
}

// Sets the reverse DNS name of an address.
message SetPtrRequest {
  // Id of the pool.
  string pool_id = 1;
  // The address.
  string address = 2;
  // Host name; empty removes it.
  string ptr = 3;
}

// Allocates the addresses of a new server.
message AllocateForServerRequest {
  // Id of the virtual machine.
  string vm_id = 1;
  // Id of the pool; empty for the first pool on the server's networks.
  string pool_id = 2;
  // Id of the tenant.
  string tenant = 3;
  // No IPv6 block, even when the pool has a prefix.
  bool no_ipv6 = 4;
  // Free text kept with the allocation.
  string reference = 5;
}

// The addresses of a server.
message ServerAddresses {
  // Id of the pool.
  string pool_id = 1;
  // MAC address of the network adapter.
  string mac = 2;
  // IPv4 address.
  string ipv4 = 3;
  // IPv4 prefix length.
  uint32 prefix_len = 4;
  // IPv4 gateway.
  string gateway = 5;
  // DNS servers.
  repeated string dns_servers = 6;
  // IPv6 block of the server.
  string ipv6_prefix = 7;
  // IPv6 address of the server in its block.
  string ipv6_address = 8;
  // IPv6 gateway.
  string ipv6_gateway = 9;
  // Prefix length the guest configures on ipv6_address (on-link, at least 64).
  uint32 ipv6_onlink_len = 10;
}

// Releases the addresses of a deleted server.
message ReleaseForServerRequest {
  // Id of the virtual machine.
  string vm_id = 1;
}

// No fields.
message ReleaseForServerResponse {
  // Addresses or "prefix" of the released /64s.
  repeated string addresses = 1;
}

// Asks for the monthly traffic.
message GetTrafficRequest {
  // Only the virtual machines of this tenant.
  string tenant = 1;
  // Only this virtual machine.
  string vm_id = 2;
  // "YYYY-MM"; empty: the current period.
  string month = 3;
}

// Traffic of one virtual machine in the period.
message VmTraffic {
  // Id of the virtual machine.
  string vm_id = 1;
  // Name of the virtual machine.
  string name = 2;
  // Id of its tenant; empty without one.
  string tenant = 3;
  // Bytes received.
  uint64 in_bytes = 4;
  // Bytes sent.
  uint64 out_bytes = 5;
  // Bytes that count toward the limit.
  uint64 billable_bytes = 6;
}

// Traffic of the period.
message TrafficReport {
  // Start of the period, RFC 3339.
  string period_start = 1;
  // End of the period, RFC 3339.
  string period_end = 2;
  // "out", "in_out" or "max".
  string billable = 3;
  // One line per virtual machine.
  repeated VmTraffic vms = 4;
}
