syntax = "proto3";

package docker.cluster.api;

import "types.proto";
import "objects.proto";
import "github.com/coreos/etcd/raft/raftpb/raft.proto";
import weak "gogoproto/gogo.proto";
import weak "plugin/plugin.proto";

// Raft defines the RPC communication between raft nodes.
service Raft {
	// Join joins an existing Manager or set of Managers to form
	// a raft cluster for the log replication backend
	rpc Join(JoinRequest) returns (JoinResponse) {}

	// Leave leaves an existing set of Managers running raft
	rpc Leave(LeaveRequest) returns (LeaveResponse) {}

	// ProcessRaftMessage sends a raft message to be processed on a raft member, it is
	// called from the Manager willing to send a message to its destination ('To' field)
	rpc ProcessRaftMessage(ProcessRaftMessageRequest) returns (ProcessRaftMessageResponse) {}
}

message JoinRequest {
	RaftNode node = 1;
}

message JoinResponse {
	repeated RaftNode members = 1;
}

message LeaveRequest {
	RaftNode node = 1;
}

message LeaveResponse {}

message ProcessRaftMessageRequest {
	option (docker.protobuf.plugin.deepcopy) = false;
	raftpb.Message message = 1;
}

message ProcessRaftMessageResponse {}

// Contains one of many protobuf encoded objects to replicate
// over the raft backend with a request ID to track when the
// action is effectively applied
message InternalRaftRequest {
	uint64 id = 1 [(gogoproto.customname) = "ID"];

	repeated StoreAction action = 2;
}

// TODO(stevvooe): Storage actions may belong in another protobuf file. They
// aren't necessarily first-class "types" in the cluster schema.

// StoreActionKind defines the operation to take on the store for the target of
// a storage action.
enum StoreActionKind {
	option (gogoproto.goproto_enum_prefix) = false;
	option (gogoproto.enum_customname) = "StoreActionKind";
	UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "StoreActionKindUnknown"]; // default value, invalid
	CREATE = 1 [(gogoproto.enumvalue_customname) = "StoreActionKindCreate"];
	UPDATE = 2 [(gogoproto.enumvalue_customname) = "StoreActionKindUpdate"];
	REMOVE = 3 [(gogoproto.enumvalue_customname) = "StoreActionKindRemove"];
}

// StoreAction defines a taret and operation to apply on the storage system.
message StoreAction {
	StoreActionKind action = 1;
	oneof target {
		Node node = 2;
		Service service = 3;
		Task task = 4;
		Network network = 5;
		Volume volume = 6;
	}
}
