Skip to content

Commit b93577c

Browse files
committed
config: add field for enabling streaming RPC endpoint
1 parent b5b790d commit b93577c

File tree

9 files changed

+55
-18
lines changed

9 files changed

+55
-18
lines changed

agent/agent.go

+2
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,8 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co
11321132
// copy it whatever the value.
11331133
cfg.RPCHoldTimeout = runtimeCfg.RPCHoldTimeout
11341134

1135+
cfg.RPCConfig = runtimeCfg.RPCConfig
1136+
11351137
if runtimeCfg.LeaveDrainTime > 0 {
11361138
cfg.LeaveDrainTime = runtimeCfg.LeaveDrainTime
11371139
}

agent/config/builder.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ import (
1616
"strings"
1717
"time"
1818

19+
"github.com/hashicorp/go-bexpr"
20+
"github.com/hashicorp/go-hclog"
21+
"github.com/hashicorp/go-multierror"
22+
"github.com/hashicorp/go-sockaddr/template"
23+
"github.com/hashicorp/memberlist"
24+
"golang.org/x/time/rate"
25+
1926
"github.com/hashicorp/consul/agent/cache"
2027
"github.com/hashicorp/consul/agent/checks"
2128
"github.com/hashicorp/consul/agent/connect/ca"
@@ -30,12 +37,6 @@ import (
3037
"github.com/hashicorp/consul/logging"
3138
"github.com/hashicorp/consul/tlsutil"
3239
"github.com/hashicorp/consul/types"
33-
"github.com/hashicorp/go-bexpr"
34-
"github.com/hashicorp/go-hclog"
35-
"github.com/hashicorp/go-multierror"
36-
"github.com/hashicorp/go-sockaddr/template"
37-
"github.com/hashicorp/memberlist"
38-
"golang.org/x/time/rate"
3940
)
4041

4142
// Load will build the configuration including the extraHead source injected
@@ -1040,6 +1041,7 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
10401041
RPCMaxConnsPerClient: b.intVal(c.Limits.RPCMaxConnsPerClient),
10411042
RPCProtocol: b.intVal(c.RPCProtocol),
10421043
RPCRateLimit: rate.Limit(b.float64Val(c.Limits.RPCRate)),
1044+
RPCConfig: consul.RPCConfig{EnableStreaming: b.boolVal(c.RPC.EnableStreaming)},
10431045
RaftProtocol: b.intVal(c.RaftProtocol),
10441046
RaftSnapshotThreshold: b.intVal(c.RaftSnapshotThreshold),
10451047
RaftSnapshotInterval: b.durationVal("raft_snapshot_interval", c.RaftSnapshotInterval),

agent/config/config.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import (
44
"encoding/json"
55
"fmt"
66

7-
"github.com/hashicorp/consul/lib/decode"
87
"github.com/hashicorp/hcl"
98
"github.com/mitchellh/mapstructure"
9+
10+
"github.com/hashicorp/consul/lib/decode"
1011
)
1112

1213
const (
@@ -257,6 +258,8 @@ type Config struct {
257258
VerifyServerHostname *bool `json:"verify_server_hostname,omitempty" hcl:"verify_server_hostname" mapstructure:"verify_server_hostname"`
258259
Watches []map[string]interface{} `json:"watches,omitempty" hcl:"watches" mapstructure:"watches"`
259260

261+
RPC RPC `mapstructure:"rpc"`
262+
260263
// This isn't used by Consul but we've documented a feature where users
261264
// can deploy their snapshot agent configs alongside their Consul configs
262265
// so we have a placeholder here so it can be parsed but this doesn't
@@ -796,3 +799,7 @@ type RawUIMetricsProxyAddHeader struct {
796799
Name *string `json:"name,omitempty" hcl:"name" mapstructure:"name"`
797800
Value *string `json:"value,omitempty" hcl:"value" mapstructure:"value"`
798801
}
802+
803+
type RPC struct {
804+
EnableStreaming *bool `json:"enable_streaming" hcl:"enable_streaming" mapstructure:"enable_streaming"`
805+
}

agent/config/runtime.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ import (
77
"strings"
88
"time"
99

10+
"github.com/hashicorp/go-uuid"
11+
"golang.org/x/time/rate"
12+
1013
"github.com/hashicorp/consul/agent/cache"
14+
"github.com/hashicorp/consul/agent/consul"
1115
"github.com/hashicorp/consul/agent/structs"
1216
"github.com/hashicorp/consul/agent/token"
1317
"github.com/hashicorp/consul/api"
1418
"github.com/hashicorp/consul/lib"
1519
"github.com/hashicorp/consul/logging"
1620
"github.com/hashicorp/consul/tlsutil"
1721
"github.com/hashicorp/consul/types"
18-
"github.com/hashicorp/go-uuid"
19-
"golang.org/x/time/rate"
2022
)
2123

2224
type RuntimeSOAConfig struct {
@@ -933,6 +935,8 @@ type RuntimeConfig struct {
933935
// hcl: protocol = int
934936
RPCProtocol int
935937

938+
RPCConfig consul.RPCConfig
939+
936940
// RaftProtocol sets the Raft protocol version to use on this server.
937941
// Defaults to 3.
938942
//

agent/config/runtime_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ import (
1818
"testing"
1919
"time"
2020

21+
"github.com/stretchr/testify/require"
22+
2123
"github.com/hashicorp/consul/agent/cache"
2224
"github.com/hashicorp/consul/agent/checks"
25+
"github.com/hashicorp/consul/agent/consul"
2326
"github.com/hashicorp/consul/agent/structs"
2427
"github.com/hashicorp/consul/agent/token"
2528
"github.com/hashicorp/consul/lib"
2629
"github.com/hashicorp/consul/logging"
2730
"github.com/hashicorp/consul/sdk/testutil"
2831
"github.com/hashicorp/consul/types"
29-
"github.com/stretchr/testify/require"
3032
)
3133

3234
type configTest struct {
@@ -5113,6 +5115,7 @@ func TestFullConfig(t *testing.T) {
51135115
"retry_join_wan": [ "PFsR02Ye", "rJdQIhER" ],
51145116
"retry_max": 913,
51155117
"retry_max_wan": 23160,
5118+
"rpc": {"enable_streaming": true},
51165119
"segment": "BC2NhTDi",
51175120
"segments": [
51185121
{
@@ -5797,6 +5800,9 @@ func TestFullConfig(t *testing.T) {
57975800
retry_join_wan = [ "PFsR02Ye", "rJdQIhER" ]
57985801
retry_max = 913
57995802
retry_max_wan = 23160
5803+
rpc {
5804+
enable_streaming = true
5805+
}
58005806
segment = "BC2NhTDi"
58015807
segments = [
58025808
{
@@ -6552,6 +6558,7 @@ func TestFullConfig(t *testing.T) {
65526558
RetryJoinMaxAttemptsLAN: 913,
65536559
RetryJoinMaxAttemptsWAN: 23160,
65546560
RetryJoinWAN: []string{"PFsR02Ye", "rJdQIhER"},
6561+
RPCConfig: consul.RPCConfig{EnableStreaming: true},
65556562
SegmentName: "BC2NhTDi",
65566563
Segments: []structs.NetworkSegment{
65576564
{
@@ -7461,6 +7468,9 @@ func TestSanitize(t *testing.T) {
74617468
"RPCMaxConnsPerClient": 0,
74627469
"RPCProtocol": 0,
74637470
"RPCRateLimit": 0,
7471+
"RPCConfig": {
7472+
"EnableStreaming": false
7473+
},
74647474
"RaftProtocol": 0,
74657475
"RaftSnapshotInterval": "0s",
74667476
"RaftSnapshotThreshold": 0,

agent/consul/config.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ import (
66
"os"
77
"time"
88

9+
"github.com/hashicorp/memberlist"
10+
"github.com/hashicorp/raft"
11+
"github.com/hashicorp/serf/serf"
12+
"golang.org/x/time/rate"
13+
914
"github.com/hashicorp/consul/agent/checks"
1015
"github.com/hashicorp/consul/agent/consul/autopilot"
1116
"github.com/hashicorp/consul/agent/structs"
1217
"github.com/hashicorp/consul/lib"
1318
"github.com/hashicorp/consul/tlsutil"
1419
"github.com/hashicorp/consul/types"
1520
"github.com/hashicorp/consul/version"
16-
"github.com/hashicorp/memberlist"
17-
"github.com/hashicorp/raft"
18-
"github.com/hashicorp/serf/serf"
19-
"golang.org/x/time/rate"
2021
)
2122

2223
const (
@@ -475,8 +476,7 @@ type Config struct {
475476
// AutoEncrypt.Sign requests.
476477
AutoEncryptAllowTLS bool
477478

478-
// TODO: godoc, set this value from Agent
479-
EnableGRPCServer bool
479+
RPCConfig RPCConfig
480480

481481
// Embedded Consul Enterprise specific configuration
482482
*EnterpriseConfig
@@ -644,3 +644,10 @@ func DefaultConfig() *Config {
644644

645645
return conf
646646
}
647+
648+
// RPCConfig settings for the RPC server
649+
//
650+
// TODO: move many settings to this struct.
651+
type RPCConfig struct {
652+
EnableStreaming bool
653+
}

agent/consul/server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ func NewServer(config *Config, flat Deps) (*Server, error) {
617617
}
618618

619619
func newGRPCHandlerFromConfig(deps Deps, config *Config, s *Server) connHandler {
620-
if !config.EnableGRPCServer {
620+
if !config.RPCConfig.EnableStreaming {
621621
return agentgrpc.NoOpHandler{Logger: deps.Logger}
622622
}
623623

contributing/checklist-adding-config-fields.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ There are four specific cases covered with increasing complexity:
5555
state for client agent's RPC client.
5656
- [ ] Add a test to `agent/agent_test.go` similar to others with prefix
5757
`TestAgent_reloadConfig*`.
58-
- [ ] Add documentation to `website/source/docs/agent/options.html.md`.
58+
- [ ] Add documentation to `website/pages/docs/agent/options.mdx`.
5959

6060
Done! You can now use your new field in a client agent by accessing
6161
`s.agent.Config.<FieldName>`.

website/pages/docs/agent/options.mdx

+5
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,11 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'."
16331633
- `rpc_max_conns_per_client` - Configures a limit of how many concurrent TCP connections a single source IP address is allowed to open to a single server. It affects both clients connections and other server connections. In general Consul clients multiplex many RPC calls over a single TCP connection so this can typically be kept low. It needs to be more than one though since servers open at least one additional connection for raft RPC, possibly more for WAN federation when using network areas, and snapshot requests from clients run over a separate TCP conn. A reasonably low limit significantly reduces the ability of an unauthenticated attacker to consume unbounded resources by holding open many connections. You may need to increase this if WAN federated servers connect via proxies or NAT gateways or similar causing many legitimate connections from a single source IP. Default value is `100` which is designed to be extremely conservative to limit issues with certain deployment patterns. Most deployments can probably reduce this safely. 100 connections on modern server hardware should not cause a significant impact on resource usage from an unauthenticated attacker though.
16341634
- `rpc_rate` - Configures the RPC rate limiter on Consul _clients_ by setting the maximum request rate that this agent is allowed to make for RPC requests to Consul servers, in requests per second. Defaults to infinite, which disables rate limiting.
16351635
- `rpc_max_burst` - The size of the token bucket used to recharge the RPC rate limiter on Consul _clients_. Defaults to 1000 tokens, and each token is good for a single RPC call to a Consul server. See https://en.wikipedia.org/wiki/Token_bucket for more details about how token bucket rate limiters operate.
1636+
1637+
- `rpc.enable_streaming` - Enable the gRPC subscribe endpoint on a Consul Server. All
1638+
Servers in all connected datacenters must have this enabled before any client can use
1639+
streaming.
1640+
16361641
- `kv_max_value_size` - **(Advanced)** Configures the maximum number of bytes for a kv request body to the [`/v1/kv`](/api/kv) endpoint. This limit defaults to [raft's](https://github.com/hashicorp/raft) suggested max size (512KB). **Note that tuning these improperly can cause Consul to fail in unexpected ways**, it may potentially affect leadership stability and prevent timely heartbeat signals by increasing RPC IO duration. This option affects the txn endpoint too, but Consul 1.7.2 introduced `txn_max_req_len` which is the preferred way to set the limit for the txn endpoint. If both limits are set, the higher one takes precedence.
16371642
- `txn_max_req_len` - **(Advanced)** Configures the maximum number of bytes for a transaction request body to the [`/v1/txn`](/api/txn) endpoint. This limit defaults to [raft's](https://github.com/hashicorp/raft) suggested max size (512KB). **Note that tuning these improperly can cause Consul to fail in unexpected ways**, it may potentially affect leadership stability and prevent timely heartbeat signals by increasing RPC IO duration.
16381643

0 commit comments

Comments
 (0)