//
//  Copyright (c) 2021 International Business Machines
//  All rights reserved.
//
//  SPDX-License-Identifier: MIT
//
//  Authors: anita.shekar@ibm.com, sandy.kaur@ibm.com
//


syntax = "proto3";

enum AddressFamily {
	ipv4 = 0;
	ipv6 = 1;
}

enum LogLevel {
	ERROR = 0;
	WARNING = 1;
	NOTICE = 2;
	INFO = 3;
	DEBUG = 4;
}

enum GwLogLevel {
	notset = 0;
	debug = 10;
	info = 20;
	warning = 30;
	error = 40;
	critical = 50;
}

service Gateway {
	// Creates a namespace from an RBD image
	rpc namespace_add(namespace_add_req) returns (nsid_status) {}

	// Creates a subsystem
	rpc create_subsystem(create_subsystem_req) returns(subsys_status) {}

	// Deletes a subsystem
	rpc delete_subsystem(delete_subsystem_req) returns(req_status) {}

	// Changes subsystem key
	rpc change_subsystem_key(change_subsystem_key_req) returns(req_status) {}

	// List namespaces
	rpc list_namespaces(list_namespaces_req) returns(namespaces_info) {}

	// Resizes a namespace
	rpc namespace_resize(namespace_resize_req) returns (req_status) {}

	// Gets namespace's IO stats
	rpc namespace_get_io_stats(namespace_get_io_stats_req) returns (namespace_io_stats_info) {}

	// Sets namespace's qos limits
	rpc namespace_set_qos_limits(namespace_set_qos_req) returns (req_status) {}

	// Changes namespace's load balancing group
	rpc namespace_change_load_balancing_group(namespace_change_load_balancing_group_req) returns (req_status) {}

	// Changes namespace's visibility
	rpc namespace_change_visibility(namespace_change_visibility_req) returns (req_status) {}

	// Set namespace's RBD trash image flag
	rpc namespace_set_rbd_trash_image(namespace_set_rbd_trash_image_req) returns (req_status) {}

	// Set namespace's auto resize flag
	rpc namespace_set_auto_resize(namespace_set_auto_resize_req) returns (req_status) {}

	// Deletes a namespace
	rpc namespace_delete(namespace_delete_req) returns (req_status) {}

	// Adds a host to a namespace
	rpc namespace_add_host(namespace_add_host_req) returns (req_status) {}

	// Deletes a host from a namespace
	rpc namespace_delete_host(namespace_delete_host_req) returns (req_status) {}

	// Adds a host to a subsystem
	rpc add_host(add_host_req) returns (req_status) {}

	// Removes a host from a subsystem
	rpc remove_host(remove_host_req) returns (req_status) {}

	// Changes a host inband authentication keys
	rpc change_host_key(change_host_key_req) returns (req_status) {}

	// List hosts
	rpc list_hosts(list_hosts_req) returns(hosts_info) {}

	// List connections
	rpc list_connections(list_connections_req) returns(connections_info) {}

	// Creates a listener for a subsystem at a given IP/Port
	rpc create_listener(create_listener_req) returns(req_status) {}

	// Deletes a listener from a subsystem at a given IP/Port
	rpc delete_listener(delete_listener_req) returns(req_status) {}

	// List listeners
	rpc list_listeners(list_listeners_req) returns(listeners_info) {}

	// List subsystems
	rpc list_subsystems(list_subsystems_req) returns(subsystems_info_cli) {}

	// Gets subsystems
	rpc get_subsystems(get_subsystems_req) returns(subsystems_info) {}

	// Set gateway ANA states
	rpc set_ana_state(ana_info) returns(req_status) {}

	// Gets spdk nvmf log flags and level
	rpc get_spdk_nvmf_log_flags_and_level(get_spdk_nvmf_log_flags_and_level_req) returns(spdk_nvmf_log_flags_and_level_info) {}

	// Disables spdk nvmf logs
	rpc disable_spdk_nvmf_logs(disable_spdk_nvmf_logs_req) returns(req_status) {}

	// Set spdk nvmf logs
	rpc set_spdk_nvmf_logs(set_spdk_nvmf_logs_req) returns(req_status) {}

	// Get gateway info
	rpc get_gateway_info(get_gateway_info_req) returns(gateway_info) {}

	// Get gateway log level
	rpc get_gateway_log_level(get_gateway_log_level_req) returns(gateway_log_level_info) {}

	// Set gateway log level
	rpc set_gateway_log_level(set_gateway_log_level_req) returns(req_status) {}

	// Show gateway listeners info
	rpc show_gateway_listeners_info(show_gateway_listeners_info_req) returns(gateway_listeners_info) {}

	// Gets gateway's stats
	rpc get_gateway_stats(get_gateway_stats_req) returns (gateway_stats_info) {}
}

// Request messages

message namespace_add_req {
	string rbd_pool_name = 1;
	string rbd_image_name = 2;
	string subsystem_nqn = 3;
	optional uint32 nsid = 4;
	uint32 block_size = 5;
	optional string uuid = 6;
	optional int32 anagrpid = 7;
	optional bool create_image = 8;
	optional uint64 size = 9;
	optional bool force = 10;
	optional bool no_auto_visible = 11;
	optional bool trash_image = 12;
	optional bool disable_auto_resize = 13;
	optional bool read_only = 14;
}

message namespace_resize_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	optional string OBSOLETE_uuid = 3;
	uint64 new_size = 4;
}

message namespace_get_io_stats_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	optional string OBSOLETE_uuid = 3;
}

message namespace_set_qos_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	optional string OBSOLETE_uuid = 3;
	optional uint64 rw_ios_per_second = 4;
	optional uint64 rw_mbytes_per_second = 5;
	optional uint64 r_mbytes_per_second = 6;
	optional uint64 w_mbytes_per_second = 7;
	optional bool force = 8;
}

message namespace_change_load_balancing_group_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	optional string OBSOLETE_uuid = 3;
	int32 anagrpid = 4;
	optional bool auto_lb_logic = 5;
}

message namespace_change_visibility_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	bool auto_visible = 3;
	optional bool force = 4;
}

message namespace_set_rbd_trash_image_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	bool trash_image = 3;
}

message namespace_set_auto_resize_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	bool auto_resize = 3;
}

message namespace_delete_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	optional string OBSOLETE_uuid = 3;
	optional bool i_am_sure = 4;
}

message namespace_add_host_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	string host_nqn = 3;
	optional bool force = 4;
}

message namespace_delete_host_req {
	string subsystem_nqn = 1;
	uint32 nsid = 2;
	string host_nqn = 3;
}

message create_subsystem_req {
	string subsystem_nqn = 1;
	string serial_number = 2;
	optional uint32 max_namespaces = 3;
	bool enable_ha = 4;
	optional bool no_group_append = 5;
	optional string dhchap_key = 6;
	optional bool key_encrypted = 7;
}

message delete_subsystem_req {
	string subsystem_nqn = 1;
	optional bool force = 2;
}

message change_subsystem_key_req {
	string subsystem_nqn = 1;
	optional string dhchap_key = 2;
}

message list_namespaces_req {
	string subsystem = 1;
	optional uint32 nsid = 2;
	optional string uuid = 3;
}

message add_host_req {
	string subsystem_nqn = 1;
	string host_nqn = 2;
	optional string psk = 3;
	optional string dhchap_key = 4;
	optional bool psk_encrypted = 5;
	optional bool key_encrypted = 6;
}

message change_host_key_req {
	string subsystem_nqn = 1;
	string host_nqn = 2;
	optional string dhchap_key = 3;
}

message remove_host_req {
	string subsystem_nqn = 1;
	string host_nqn = 2;
}

message list_hosts_req {
	string subsystem = 1;
	optional bool clear_alerts = 2;
}

message list_connections_req {
	string subsystem = 1;
}

message create_listener_req {
	string nqn = 1;
	string host_name = 2;
	string traddr = 3;
	optional AddressFamily adrfam = 5;
	optional uint32 trsvcid = 6;
	optional bool secure = 7;
	optional bool verify_host_name = 8;
}

message delete_listener_req {
	string nqn = 1;
	string host_name = 2;
	string traddr = 3;
	optional AddressFamily adrfam = 5;
	optional uint32 trsvcid = 6;
	optional bool force = 7;
}

message list_listeners_req {
	string subsystem = 1;
}

message list_subsystems_req {
	optional string subsystem_nqn = 1;
	optional string serial_number = 2;
}

message get_subsystems_req {
}

message get_spdk_nvmf_log_flags_and_level_req {
	optional bool all_log_flags = 1;
}

message disable_spdk_nvmf_logs_req {
	repeated string extra_log_flags = 1;
}

message set_spdk_nvmf_logs_req {
	optional LogLevel log_level = 1;
	optional LogLevel print_level = 2;
	repeated string extra_log_flags = 3;
}

message get_gateway_info_req {
	optional string cli_version = 1;
}

message get_gateway_log_level_req {
}

message set_gateway_log_level_req {
	GwLogLevel log_level = 1;
}

message show_gateway_listeners_info_req {
	string subsystem_nqn = 1;
}

message get_gateway_stats_req {
}

// From https://nvmexpress.org/wp-content/uploads/NVM-Express-1_4-2019.06.10-Ratified.pdf page 138
// Asymmetric Namespace Access state for all namespaces in this ANA
// Group when accessed through this controller.
// Value Description Reference
// 01h ANA Optimized state 8.20.3.1
// 02h ANA Non-Optimized state 8.20.3.2
// 03h ANA Inaccessible state 8.20.3.3
// 04h ANA Persistent Loss state 8.20.3.4
// 0Fh ANA Change state 8.20.3.5
// All others Reserved
enum ana_state {
	UNSET         = 0;
	OPTIMIZED     = 1;
	NON_OPTIMIZED = 2;
	INACCESSIBLE  = 3;
}

message ana_group_state {
	uint32     grp_id = 1;  // groupd id
	ana_state  state  = 2;  // ANA state
}

message nqn_ana_states {
	string     nqn                     = 1; // subsystem nqn
	repeated   ana_group_state  states = 2; // list of group states
}

message ana_info {
	repeated nqn_ana_states states = 1; // list of nqn states
}

// Return messages 

message req_status {
	int32 status = 1;
	string error_message = 2;
}

message subsys_status {
	int32 status = 1;
	string error_message = 2;
	string nqn = 3;
}

message nsid_status {
	int32 status = 1;
	string error_message = 2;
	uint32 nsid = 3;
}

message subsystems_info {
	repeated subsystem subsystems = 1;
}

message subsystem {
	string nqn = 1;
	string subtype = 2;
	repeated listen_address listen_addresses = 3;
	repeated host hosts = 4;
	bool allow_any_host = 5;
	optional string serial_number = 6;
	optional string model_number = 7;
	optional uint32 max_namespaces = 8;
	optional uint32 min_cntlid = 9;
	optional uint32 max_cntlid = 10;
	repeated namespace namespaces = 11;
	optional bool has_dhchap_key = 12;
}

message listen_address {
	string trtype = 1;
	string adrfam = 2;
	string traddr = 3;
	string trsvcid = 4;
	optional string transport = 5;
	optional bool secure = 6;
}

message namespace {
	uint32 nsid = 1;
	string name = 2;
	optional string bdev_name = 3;
	optional string nguid = 4;
	optional string uuid = 5;
	optional uint32 anagrpid = 6;
	optional string nonce = 7;
	optional bool auto_visible = 8;
	repeated string hosts = 9;
}

message subsystems_info_cli {
	int32 status = 1;
	string error_message = 2;
	repeated subsystem_cli subsystems = 3;
}

message subsystem_cli {
	string nqn = 1;
	bool enable_ha = 2;
	string serial_number = 3;
	string model_number = 4;
	uint32 min_cntlid = 5;
	uint32 max_cntlid = 6;
	uint32 namespace_count = 7;
	string subtype = 8;
	uint32 max_namespaces = 9;
	optional bool has_dhchap_key = 10;
	optional bool allow_any_host = 11;
	optional bool created_without_key = 12;
}

message gateway_info {
	string cli_version = 1;
	string version = 2;
	string name = 3;
	string group = 4;
	string addr = 5;
	string port = 6;
	bool bool_status = 7;
	int32 status = 8;
	string error_message = 9;
	optional string spdk_version = 10;
	uint32 load_balancing_group = 11;
	string hostname = 12;
	optional uint32 max_subsystems = 13;
	optional uint32 max_namespaces = 14;
	optional uint32 max_hosts_per_subsystem = 15;
	optional uint32 max_namespaces_per_subsystem = 16;
	optional uint32 max_hosts = 17;
}

message cli_version {
	int32 status = 1;
	string error_message = 2;
	string version = 3;
}

message gw_version {
	int32 status = 1;
	string error_message = 2;
	string version = 3;
}

message poll_group_transport_info {
	string trtype = 1;
}

message poll_group_info {
	string name = 1;
	uint32 admin_qpairs = 2;
	uint32 io_qpairs = 3;
	uint32 current_admin_qpairs = 4;
	uint32 current_io_qpairs = 5;
	uint64 pending_bdev_io = 6;
	uint64 completed_nvme_io = 7;
        repeated poll_group_transport_info transports = 8;
}

message gateway_stats_info {
	int32 status = 1;
	string error_message = 2;
	uint64 tick_rate = 3;
        repeated poll_group_info poll_groups = 4;
}

message listener_info {
	string host_name = 1;
	string trtype = 2;
	AddressFamily adrfam = 3;
	string traddr = 4;
	uint32 trsvcid = 5;
	optional bool secure = 6;
	optional bool active = 7;
}

message listeners_info {
	int32 status = 1;
	string error_message = 2;
	repeated listener_info listeners = 3;
}

message gateway_listener_info {
	listener_info listener = 1;
	repeated ana_group_state lb_states = 2;
}

message gateway_listeners_info {
	int32 status = 1;
	string error_message = 2;
	repeated gateway_listener_info gw_listeners = 3;
}

message host {
	string nqn = 1;
	optional bool use_psk = 2;
	optional bool use_dhchap = 3;
	optional bool disconnected_due_to_keepalive_timeout = 4;
}

message hosts_info {
	int32 status = 1;
	string error_message = 2;
	bool allow_any_host = 3;
	string subsystem_nqn = 4;
	repeated host hosts = 5;
}

message connection {
	string nqn = 1;
	string traddr = 2;
	uint32 trsvcid = 3;
	string trtype = 4;
	AddressFamily adrfam = 5;
	bool connected = 6;
	int32 qpairs_count = 7;
	int32 controller_id = 8;
	optional bool secure = 9;
	optional bool use_psk = 10;
	optional bool use_dhchap = 11;
        optional string subsystem = 12;
	optional bool disconnected_due_to_keepalive_timeout = 13;
}

message connections_info {
	int32 status = 1;
	string error_message = 2;
	string subsystem_nqn = 3;
	repeated connection connections = 4;
}

message namespace_cli {
	uint32 nsid = 1;
	string bdev_name = 2;
	string rbd_image_name = 3;
	string rbd_pool_name = 4;
	uint32 load_balancing_group = 5;
	uint32 block_size = 6;
	uint64 rbd_image_size = 7;
	string uuid = 8;
	uint64 rw_ios_per_second = 9;
	uint64 rw_mbytes_per_second = 10;
	uint64 r_mbytes_per_second = 11;
	uint64 w_mbytes_per_second = 12;
	bool auto_visible = 13;
	repeated string hosts = 14;
	optional string ns_subsystem_nqn = 15;
	optional bool trash_image = 16;
	optional bool disable_auto_resize = 17;
	optional bool read_only = 18;
        optional string cluster_name = 19;
        optional uint32 configured_load_balancing_group = 20;
	optional bool image_was_shrunk = 21;
}

message namespaces_info {
	int32 status = 1;
	string error_message = 2;
	string subsystem_nqn = 3;
	repeated namespace_cli namespaces = 4;
}

message namespace_io_error {
	string name = 1;
	uint32 value = 2;
}

message namespace_io_stats_info {
	int32 status = 1;
	string error_message = 2;
	string subsystem_nqn = 3;
	uint32 nsid = 4;
	optional string uuid = 5;
	string bdev_name = 6;
	uint64 tick_rate = 7;
	uint64 ticks = 8;
	uint64 bytes_read = 9;
	uint64 num_read_ops = 10;
	uint64 bytes_written = 11;
	uint64 num_write_ops = 12;
	uint64 bytes_unmapped = 13;
	uint64 num_unmap_ops = 14;
	uint64 read_latency_ticks = 15;
	uint64 max_read_latency_ticks = 16;
	uint64 min_read_latency_ticks = 17;
	uint64 write_latency_ticks = 18;
	uint64 max_write_latency_ticks = 19;
	uint64 min_write_latency_ticks = 20;
	uint64 unmap_latency_ticks = 21;
	uint64 max_unmap_latency_ticks = 22;
	uint64 min_unmap_latency_ticks = 23;
	uint64 copy_latency_ticks = 24;
	uint64 max_copy_latency_ticks = 25;
	uint64 min_copy_latency_ticks = 26;
	repeated namespace_io_error io_error = 27;
}

message spdk_log_flag_info {
	string name = 1;
	bool enabled = 2;
}

message spdk_nvmf_log_flags_and_level_info {
	int32 status = 1;
	string error_message = 2;
	repeated spdk_log_flag_info nvmf_log_flags = 3;
	LogLevel log_level = 4;
	LogLevel log_print_level = 5;
}

message gateway_log_level_info {
	int32 status = 1;
	string error_message = 2;
	GwLogLevel log_level = 3;
}

