// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
syntax = "proto3" ;
package hashicorp . consul.internal.peerstream ;
import "annotations/ratelimit/ratelimit.proto" ;
import "google/protobuf/any.proto" ;
import "private/pbpeering/peering.proto" ;
import "private/pbservice/node.proto" ;
// TODO(peering): Handle this some other way
import "private/pbstatus/status.proto" ;
// TODO(peering): comments
// TODO(peering): also duplicate the pbservice, some pbpeering, and ca stuff.
service PeerStreamService {
// StreamResources opens an event stream for resources to share between peers, such as services.
// Events are streamed as they happen.
// buf:lint:ignore RPC_REQUEST_STANDARD_NAME
// buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
// buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE
rpc StreamResources ( stream ReplicationMessage ) returns ( stream ReplicationMessage ) {
option ( hashicorp.consul.internal.ratelimit.spec ) = {
operation_type : OPERATION_TYPE_READ ,
operation_category : OPERATION_CATEGORY_PEER_STREAM
} ;
}
// ExchangeSecret is a unary RPC for exchanging the one-time establishment secret
// for a long-lived stream secret.
rpc ExchangeSecret ( ExchangeSecretRequest ) returns ( ExchangeSecretResponse ) {
option ( hashicorp.consul.internal.ratelimit.spec ) = {
operation_type : OPERATION_TYPE_WRITE ,
operation_category : OPERATION_CATEGORY_PEER_STREAM
} ;
}
}
message ReplicationMessage {
oneof Payload {
Open open = 1 ;
Request request = 2 ;
Response response = 3 ;
Terminated terminated = 4 ;
Heartbeat heartbeat = 5 ;
}
// Open is the initial message send by a dialing peer to establish the peering stream.
message Open {
// An identifier for the peer making the request.
// This identifier is provisioned by the serving peer prior to the request from the dialing peer.
string PeerID = 1 ;
// StreamSecretID contains the long-lived secret from stream authn/authz.
string StreamSecretID = 2 ;
// Remote contains metadata about the remote peer.
hashicorp.consul.internal.peering.RemoteInfo Remote = 3 ;
}
// A Request requests to subscribe to a resource of a given type.
message Request {
// An identifier for the peer making the request.
// This identifier is provisioned by the serving peer prior to the request from the dialing peer.
string PeerID = 1 ;
// ResponseNonce corresponding to that of the response being ACKed or NACKed.
// Initial subscription requests will have an empty nonce.
// The nonce is generated and incremented by the exporting peer.
// TODO
string ResponseNonce = 2 ;
// The type URL for the resource being requested or ACK/NACKed.
string ResourceURL = 3 ;
// The error if the previous response was not applied successfully.
// This field is empty in the first subscription request.
status.Status Error = 5 ;
}
// A Response contains resources corresponding to a subscription request.
message Response {
// Nonce identifying a response in a stream.
string Nonce = 1 ;
// The type URL of resource being returned.
string ResourceURL = 2 ;
// An identifier for the resource being returned.
// This could be the SPIFFE ID of the service.
string ResourceID = 3 ;
// The resource being returned.
google.protobuf.Any Resource = 4 ;
// REQUIRED. The operation to be performed in relation to the resource.
Operation operation = 5 ;
}
// Terminated is sent when a peering is deleted locally.
// This message signals to the peer that they should clean up their local state about the peering.
message Terminated { }
// Heartbeat is sent to verify that the connection is still active.
message Heartbeat { }
}
// Operation enumerates supported operations for replicated resources.
enum Operation {
OPERATION_UNSPECIFIED = 0 ;
// UPSERT represents a create or update event.
OPERATION_UPSERT = 1 ;
}
// LeaderAddress is sent when the peering service runs on a consul node
// that is not a leader. The node either lost leadership, or never was a leader.
message LeaderAddress {
// address is an ip:port best effort hint at what could be the cluster leader's address
string address = 1 ;
}
// ExportedService is one of the types of data returned via peer stream replication.
message ExportedService {
repeated hashicorp.consul.internal.service.CheckServiceNode Nodes = 1 ;
}
// ExportedServiceList is one of the types of data returned via peer stream replication.
message ExportedServiceList {
// The identifiers for the services being exported.
repeated string Services = 1 ;
}
message ExchangeSecretRequest {
// PeerID is the ID of the peering, as determined by the cluster that generated the
// peering token.
string PeerID = 1 ;
// EstablishmentSecret is the one-time-use secret encoded in the received peering token.
string EstablishmentSecret = 2 ;
}
message ExchangeSecretResponse {
// StreamSecret is the long-lived secret to be used for authentication with the
// peering stream handler.
string StreamSecret = 1 ;
}