Merge Consul OSS branch 'master' at commit 4eb73973b6e53336fd505dc727ac84c1f7e78872
This commit is contained in:
commit
3224bea082
|
@ -4,9 +4,12 @@ IMPROVEMENTS
|
|||
|
||||
* agent: improve startup message when no error occurs [[GH-5896](https://github.com/hashicorp/consul/issues/5896)]
|
||||
* agent: make sure client agent rate limits apply when hitting the client interface on a server directly [[GH-5927](https://github.com/hashicorp/consul/pull/5927)]
|
||||
* agent: use stale requests when performing full sync [[GH-5873](https://github.com/hashicorp/consul/pull/5873)]
|
||||
* agent: transfer leadership when establishLeadership fails [[GH-5247](https://github.com/hashicorp/consul/pull/5247)]
|
||||
* connect: provide -admin-access-log-path for envoy [[GH-5858](https://github.com/hashicorp/consul/pull/5858)]
|
||||
* connect: upgrade Envoy xDS protocol to support Envoy 1.10 [[GH-5872](https://github.com/hashicorp/consul/pull/5872)]
|
||||
|
||||
* ui: Improve linking between sidecars and proxies and their services/service instances [[GH-5944](https://github.com/hashicorp/consul/pull/5944)]
|
||||
* ui: Add ability to search for tokens by policy, role or service identity name [[GH-5811](https://github.com/hashicorp/consul/pull/5811)]
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
|
@ -14,6 +17,7 @@ BUG FIXES:
|
|||
* api: update link to agent caching in comments [[GH-5935](https://github.com/hashicorp/consul/pull/5935)]
|
||||
* connect: fix proxy address formatting for IPv6 addresses [[GH-5460](https://github.com/hashicorp/consul/issues/5460)]
|
||||
* ui: fix service instance linking when multiple non-unique service id's exist on multiple nodes [[GH-5933](https://github.com/hashicorp/consul/pull/5933)]
|
||||
* ui: Improve error messaging for ACL policies [[GH-5836](https://github.com/hashicorp/consul/pull/5836)]
|
||||
* txn: Fixed an issue that would allow a CAS operation on a service to work when it shouldn't have. [[GH-5971](https://github.com/hashicorp/consul/pull/5971)]
|
||||
|
||||
## 1.5.1 (May 22, 2019)
|
||||
|
|
|
@ -915,6 +915,7 @@ func (a *Agent) consulConfig() (*consul.Config, error) {
|
|||
base.CoordinateUpdateBatchSize = a.config.ConsulCoordinateUpdateBatchSize
|
||||
base.CoordinateUpdateMaxBatches = a.config.ConsulCoordinateUpdateMaxBatches
|
||||
base.CoordinateUpdatePeriod = a.config.ConsulCoordinateUpdatePeriod
|
||||
base.CheckOutputMaxSize = a.config.CheckOutputMaxSize
|
||||
|
||||
base.RaftConfig.HeartbeatTimeout = a.config.ConsulRaftHeartbeatTimeout
|
||||
base.RaftConfig.LeaderLeaseTimeout = a.config.ConsulRaftLeaderLeaseTimeout
|
||||
|
@ -971,6 +972,9 @@ func (a *Agent) consulConfig() (*consul.Config, error) {
|
|||
if a.config.Bootstrap {
|
||||
base.Bootstrap = true
|
||||
}
|
||||
if a.config.CheckOutputMaxSize > 0 {
|
||||
base.CheckOutputMaxSize = a.config.CheckOutputMaxSize
|
||||
}
|
||||
if a.config.RejoinAfterLeave {
|
||||
base.RejoinAfterLeave = true
|
||||
}
|
||||
|
@ -2248,6 +2252,13 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
|
||||
// Check if already registered
|
||||
if chkType != nil {
|
||||
maxOutputSize := a.config.CheckOutputMaxSize
|
||||
if maxOutputSize == 0 {
|
||||
maxOutputSize = checks.DefaultBufSize
|
||||
}
|
||||
if chkType.OutputMaxSize > 0 && maxOutputSize > chkType.OutputMaxSize {
|
||||
maxOutputSize = chkType.OutputMaxSize
|
||||
}
|
||||
switch {
|
||||
|
||||
case chkType.IsTTL():
|
||||
|
@ -2257,10 +2268,11 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
}
|
||||
|
||||
ttl := &checks.CheckTTL{
|
||||
Notify: a.State,
|
||||
CheckID: check.CheckID,
|
||||
TTL: chkType.TTL,
|
||||
Logger: a.logger,
|
||||
Notify: a.State,
|
||||
CheckID: check.CheckID,
|
||||
TTL: chkType.TTL,
|
||||
Logger: a.logger,
|
||||
OutputMaxSize: maxOutputSize,
|
||||
}
|
||||
|
||||
// Restore persisted state, if any
|
||||
|
@ -2294,6 +2306,7 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
Interval: chkType.Interval,
|
||||
Timeout: chkType.Timeout,
|
||||
Logger: a.logger,
|
||||
OutputMaxSize: maxOutputSize,
|
||||
TLSClientConfig: tlsClientConfig,
|
||||
}
|
||||
http.Start()
|
||||
|
@ -2361,7 +2374,7 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
}
|
||||
|
||||
if a.dockerClient == nil {
|
||||
dc, err := checks.NewDockerClient(os.Getenv("DOCKER_HOST"), checks.BufSize)
|
||||
dc, err := checks.NewDockerClient(os.Getenv("DOCKER_HOST"), int64(maxOutputSize))
|
||||
if err != nil {
|
||||
a.logger.Printf("[ERR] agent: error creating docker client: %s", err)
|
||||
return err
|
||||
|
@ -2396,14 +2409,14 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
check.CheckID, checks.MinInterval)
|
||||
chkType.Interval = checks.MinInterval
|
||||
}
|
||||
|
||||
monitor := &checks.CheckMonitor{
|
||||
Notify: a.State,
|
||||
CheckID: check.CheckID,
|
||||
ScriptArgs: chkType.ScriptArgs,
|
||||
Interval: chkType.Interval,
|
||||
Timeout: chkType.Timeout,
|
||||
Logger: a.logger,
|
||||
Notify: a.State,
|
||||
CheckID: check.CheckID,
|
||||
ScriptArgs: chkType.ScriptArgs,
|
||||
Interval: chkType.Interval,
|
||||
Timeout: chkType.Timeout,
|
||||
Logger: a.logger,
|
||||
OutputMaxSize: maxOutputSize,
|
||||
}
|
||||
monitor.Start()
|
||||
a.checkMonitors[check.CheckID] = monitor
|
||||
|
@ -2878,7 +2891,7 @@ func (a *Agent) updateTTLCheck(checkID types.CheckID, status, output string) err
|
|||
}
|
||||
|
||||
// Set the status through CheckTTL to reset the TTL.
|
||||
check.SetStatus(status, output)
|
||||
outputTruncated := check.SetStatus(status, output)
|
||||
|
||||
// We don't write any files in dev mode so bail here.
|
||||
if a.config.DataDir == "" {
|
||||
|
@ -2887,7 +2900,7 @@ func (a *Agent) updateTTLCheck(checkID types.CheckID, status, output string) err
|
|||
|
||||
// Persist the state so the TTL check can come up in a good state after
|
||||
// an agent restart, especially with long TTL values.
|
||||
if err := a.persistCheckState(check, status, output); err != nil {
|
||||
if err := a.persistCheckState(check, status, outputTruncated); err != nil {
|
||||
return fmt.Errorf("failed persisting state for check %q: %s", checkID, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/debug"
|
||||
"github.com/hashicorp/consul/agent/local"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
@ -725,12 +724,6 @@ func (s *HTTPServer) AgentCheckUpdate(resp http.ResponseWriter, req *http.Reques
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
total := len(update.Output)
|
||||
if total > checks.BufSize {
|
||||
update.Output = fmt.Sprintf("%s ... (captured %d of %d bytes)",
|
||||
update.Output[:checks.BufSize], checks.BufSize, total)
|
||||
}
|
||||
|
||||
checkID := types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/update/"))
|
||||
|
||||
// Get the provided token, if any, and vet against any ACL policies.
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/config"
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/debug"
|
||||
|
@ -2299,7 +2298,8 @@ func TestAgent_FailCheck_ACLDeny(t *testing.T) {
|
|||
|
||||
func TestAgent_UpdateCheck(t *testing.T) {
|
||||
t.Parallel()
|
||||
a := NewTestAgent(t, t.Name(), "")
|
||||
maxChecksSize := 256
|
||||
a := NewTestAgent(t, t.Name(), fmt.Sprintf("check_output_max_size=%d", maxChecksSize))
|
||||
defer a.Shutdown()
|
||||
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||||
|
||||
|
@ -2340,7 +2340,7 @@ func TestAgent_UpdateCheck(t *testing.T) {
|
|||
t.Run("log output limit", func(t *testing.T) {
|
||||
args := checkUpdate{
|
||||
Status: api.HealthPassing,
|
||||
Output: strings.Repeat("-= bad -=", 5*checks.BufSize),
|
||||
Output: strings.Repeat("-= bad -=", 5*maxChecksSize),
|
||||
}
|
||||
req, _ := http.NewRequest("PUT", "/v1/agent/check/update/test", jsonReader(args))
|
||||
resp := httptest.NewRecorder()
|
||||
|
@ -2359,8 +2359,8 @@ func TestAgent_UpdateCheck(t *testing.T) {
|
|||
// rough check that the output buffer was cut down so this test
|
||||
// isn't super brittle.
|
||||
state := a.State.Checks()["test"]
|
||||
if state.Status != api.HealthPassing || len(state.Output) > 2*checks.BufSize {
|
||||
t.Fatalf("bad: %v", state)
|
||||
if state.Status != api.HealthPassing || len(state.Output) > 2*maxChecksSize {
|
||||
t.Fatalf("bad: %v, (len:=%d)", state, len(state.Output))
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1586,7 +1586,7 @@ func TestAgent_updateTTLCheck(t *testing.T) {
|
|||
t.Parallel()
|
||||
a := NewTestAgent(t, t.Name(), "")
|
||||
defer a.Shutdown()
|
||||
|
||||
checkBufSize := 100
|
||||
health := &structs.HealthCheck{
|
||||
Node: "foo",
|
||||
CheckID: "mem",
|
||||
|
@ -1594,7 +1594,8 @@ func TestAgent_updateTTLCheck(t *testing.T) {
|
|||
Status: api.HealthCritical,
|
||||
}
|
||||
chk := &structs.CheckType{
|
||||
TTL: 15 * time.Second,
|
||||
TTL: 15 * time.Second,
|
||||
OutputMaxSize: checkBufSize,
|
||||
}
|
||||
|
||||
// Add check and update it.
|
||||
|
@ -1614,6 +1615,19 @@ func TestAgent_updateTTLCheck(t *testing.T) {
|
|||
if status.Output != "foo" {
|
||||
t.Fatalf("bad: %v", status)
|
||||
}
|
||||
|
||||
if err := a.updateTTLCheck("mem", api.HealthCritical, strings.Repeat("--bad-- ", 5*checkBufSize)); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Ensure we have a check mapping.
|
||||
status = a.State.Checks()["mem"]
|
||||
if status.Status != api.HealthCritical {
|
||||
t.Fatalf("bad: %v", status)
|
||||
}
|
||||
if len(status.Output) > checkBufSize*2 {
|
||||
t.Fatalf("bad: %v", len(status.Output))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgent_PersistService(t *testing.T) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -28,10 +28,10 @@ const (
|
|||
// Otherwise we risk fork bombing a system.
|
||||
MinInterval = time.Second
|
||||
|
||||
// BufSize is the maximum size of the captured
|
||||
// check output. Prevents an enormous buffer
|
||||
// DefaultBufSize is the maximum size of the captured
|
||||
// check output by defaut. Prevents an enormous buffer
|
||||
// from being captured
|
||||
BufSize = 4 * 1024 // 4KB
|
||||
DefaultBufSize = 4 * 1024 // 4KB
|
||||
|
||||
// UserAgent is the value of the User-Agent header
|
||||
// for HTTP health checks.
|
||||
|
@ -56,13 +56,14 @@ type CheckNotifier interface {
|
|||
// determine the health of a given check. It is compatible with
|
||||
// nagios plugins and expects the output in the same format.
|
||||
type CheckMonitor struct {
|
||||
Notify CheckNotifier
|
||||
CheckID types.CheckID
|
||||
Script string
|
||||
ScriptArgs []string
|
||||
Interval time.Duration
|
||||
Timeout time.Duration
|
||||
Logger *log.Logger
|
||||
Notify CheckNotifier
|
||||
CheckID types.CheckID
|
||||
Script string
|
||||
ScriptArgs []string
|
||||
Interval time.Duration
|
||||
Timeout time.Duration
|
||||
Logger *log.Logger
|
||||
OutputMaxSize int
|
||||
|
||||
stop bool
|
||||
stopCh chan struct{}
|
||||
|
@ -122,7 +123,7 @@ func (c *CheckMonitor) check() {
|
|||
}
|
||||
|
||||
// Collect the output
|
||||
output, _ := circbuf.NewBuffer(BufSize)
|
||||
output, _ := circbuf.NewBuffer(int64(c.OutputMaxSize))
|
||||
cmd.Stdout = output
|
||||
cmd.Stderr = output
|
||||
exec.SetSysProcAttr(cmd)
|
||||
|
@ -222,12 +223,17 @@ type CheckTTL struct {
|
|||
stop bool
|
||||
stopCh chan struct{}
|
||||
stopLock sync.Mutex
|
||||
|
||||
OutputMaxSize int
|
||||
}
|
||||
|
||||
// Start is used to start a check ttl, runs until Stop()
|
||||
func (c *CheckTTL) Start() {
|
||||
c.stopLock.Lock()
|
||||
defer c.stopLock.Unlock()
|
||||
if c.OutputMaxSize < 1 {
|
||||
c.OutputMaxSize = DefaultBufSize
|
||||
}
|
||||
c.stop = false
|
||||
c.stopCh = make(chan struct{})
|
||||
c.timer = time.NewTimer(c.TTL)
|
||||
|
@ -275,16 +281,22 @@ func (c *CheckTTL) getExpiredOutput() string {
|
|||
|
||||
// SetStatus is used to update the status of the check,
|
||||
// and to renew the TTL. If expired, TTL is restarted.
|
||||
func (c *CheckTTL) SetStatus(status, output string) {
|
||||
// output is returned (might be truncated)
|
||||
func (c *CheckTTL) SetStatus(status, output string) string {
|
||||
c.Logger.Printf("[DEBUG] agent: Check %q status is now %s", c.CheckID, status)
|
||||
total := len(output)
|
||||
if total > c.OutputMaxSize {
|
||||
output = fmt.Sprintf("%s ... (captured %d of %d bytes)",
|
||||
output[:c.OutputMaxSize], c.OutputMaxSize, total)
|
||||
}
|
||||
c.Notify.UpdateCheck(c.CheckID, status, output)
|
||||
|
||||
// Store the last output so we can retain it if the TTL expires.
|
||||
c.lastOutputLock.Lock()
|
||||
c.lastOutput = output
|
||||
c.lastOutputLock.Unlock()
|
||||
|
||||
c.timer.Reset(c.TTL)
|
||||
return output
|
||||
}
|
||||
|
||||
// CheckHTTP is used to periodically make an HTTP request to
|
||||
|
@ -303,6 +315,7 @@ type CheckHTTP struct {
|
|||
Timeout time.Duration
|
||||
Logger *log.Logger
|
||||
TLSClientConfig *tls.Config
|
||||
OutputMaxSize int
|
||||
|
||||
httpClient *http.Client
|
||||
stop bool
|
||||
|
@ -339,6 +352,9 @@ func (c *CheckHTTP) Start() {
|
|||
} else if c.Interval < 10*time.Second {
|
||||
c.httpClient.Timeout = c.Interval
|
||||
}
|
||||
if c.OutputMaxSize < 1 {
|
||||
c.OutputMaxSize = DefaultBufSize
|
||||
}
|
||||
}
|
||||
|
||||
c.stop = false
|
||||
|
@ -413,7 +429,7 @@ func (c *CheckHTTP) check() {
|
|||
defer resp.Body.Close()
|
||||
|
||||
// Read the response into a circular buffer to limit the size
|
||||
output, _ := circbuf.NewBuffer(BufSize)
|
||||
output, _ := circbuf.NewBuffer(int64(c.OutputMaxSize))
|
||||
if _, err := io.Copy(output, resp.Body); err != nil {
|
||||
c.Logger.Printf("[WARN] agent: Check %q error while reading body: %s", c.CheckID, err)
|
||||
}
|
||||
|
|
|
@ -44,11 +44,12 @@ func TestCheckMonitor_Script(t *testing.T) {
|
|||
t.Run(tt.status, func(t *testing.T) {
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckMonitor{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
Script: tt.script,
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
Script: tt.script,
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -79,11 +80,12 @@ func TestCheckMonitor_Args(t *testing.T) {
|
|||
t.Run(tt.status, func(t *testing.T) {
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckMonitor{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: tt.args,
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: tt.args,
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -103,12 +105,13 @@ func TestCheckMonitor_Timeout(t *testing.T) {
|
|||
// t.Parallel() // timing test. no parallel
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckMonitor{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"sh", "-c", "sleep 1 && exit 0"},
|
||||
Interval: 50 * time.Millisecond,
|
||||
Timeout: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"sh", "-c", "sleep 1 && exit 0"},
|
||||
Interval: 50 * time.Millisecond,
|
||||
Timeout: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -128,11 +131,12 @@ func TestCheckMonitor_RandomStagger(t *testing.T) {
|
|||
// t.Parallel() // timing test. no parallel
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckMonitor{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"sh", "-c", "exit 0"},
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"sh", "-c", "exit 0"},
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -153,11 +157,12 @@ func TestCheckMonitor_LimitOutput(t *testing.T) {
|
|||
t.Parallel()
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckMonitor{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"od", "-N", "81920", "/dev/urandom"},
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
ScriptArgs: []string{"od", "-N", "81920", "/dev/urandom"},
|
||||
Interval: 25 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -165,7 +170,7 @@ func TestCheckMonitor_LimitOutput(t *testing.T) {
|
|||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
// Allow for extra bytes for the truncation message
|
||||
if len(notif.Output("foo")) > BufSize+100 {
|
||||
if len(notif.Output("foo")) > DefaultBufSize+100 {
|
||||
t.Fatalf("output size is too long")
|
||||
}
|
||||
}
|
||||
|
@ -287,7 +292,7 @@ func TestCheckHTTP(t *testing.T) {
|
|||
}
|
||||
|
||||
// Body larger than 4k limit
|
||||
body := bytes.Repeat([]byte{'a'}, 2*BufSize)
|
||||
body := bytes.Repeat([]byte{'a'}, 2*DefaultBufSize)
|
||||
w.WriteHeader(tt.code)
|
||||
w.Write(body)
|
||||
}))
|
||||
|
@ -295,13 +300,14 @@ func TestCheckHTTP(t *testing.T) {
|
|||
|
||||
notif := mock.NewNotify()
|
||||
check := &CheckHTTP{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
HTTP: server.URL,
|
||||
Method: tt.method,
|
||||
Header: tt.header,
|
||||
Interval: 10 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("foo"),
|
||||
HTTP: server.URL,
|
||||
Method: tt.method,
|
||||
OutputMaxSize: DefaultBufSize,
|
||||
Header: tt.header,
|
||||
Interval: 10 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
@ -313,15 +319,52 @@ func TestCheckHTTP(t *testing.T) {
|
|||
if got, want := notif.State("foo"), tt.status; got != want {
|
||||
r.Fatalf("got state %q want %q", got, want)
|
||||
}
|
||||
// Allow slightly more data than BufSize, for the header
|
||||
if n := len(notif.Output("foo")); n > (BufSize + 256) {
|
||||
r.Fatalf("output too long: %d (%d-byte limit)", n, BufSize)
|
||||
// Allow slightly more data than DefaultBufSize, for the header
|
||||
if n := len(notif.Output("foo")); n > (DefaultBufSize + 256) {
|
||||
r.Fatalf("output too long: %d (%d-byte limit)", n, DefaultBufSize)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckMaxOutputSize(t *testing.T) {
|
||||
t.Parallel()
|
||||
timeout := 5 * time.Millisecond
|
||||
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
|
||||
body := bytes.Repeat([]byte{'x'}, 2*DefaultBufSize)
|
||||
writer.WriteHeader(200)
|
||||
writer.Write(body)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
notif := mock.NewNotify()
|
||||
maxOutputSize := 32
|
||||
check := &CheckHTTP{
|
||||
Notify: notif,
|
||||
CheckID: types.CheckID("bar"),
|
||||
HTTP: server.URL + "/v1/agent/self",
|
||||
Timeout: timeout,
|
||||
Interval: 2 * time.Millisecond,
|
||||
Logger: log.New(ioutil.Discard, uniqueID(), log.LstdFlags),
|
||||
OutputMaxSize: maxOutputSize,
|
||||
}
|
||||
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
retry.Run(t, func(r *retry.R) {
|
||||
if got, want := notif.Updates("bar"), 2; got < want {
|
||||
r.Fatalf("got %d updates want at least %d", got, want)
|
||||
}
|
||||
if got, want := notif.State("bar"), api.HealthPassing; got != want {
|
||||
r.Fatalf("got state %q want %q", got, want)
|
||||
}
|
||||
if got, want := notif.Output("bar"), "HTTP GET "+server.URL+"/v1/agent/self: 200 OK Output: "+strings.Repeat("x", maxOutputSize); got != want {
|
||||
r.Fatalf("got state %q want %q", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckHTTPTimeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
timeout := 5 * time.Millisecond
|
||||
|
@ -372,7 +415,7 @@ func TestCheckHTTP_disablesKeepAlives(t *testing.T) {
|
|||
func largeBodyHandler(code int) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Body larger than 4k limit
|
||||
body := bytes.Repeat([]byte{'a'}, 2*BufSize)
|
||||
body := bytes.Repeat([]byte{'a'}, 2*DefaultBufSize)
|
||||
w.WriteHeader(code)
|
||||
w.Write(body)
|
||||
})
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/connect/ca"
|
||||
"github.com/hashicorp/consul/agent/consul"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
@ -786,6 +787,7 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
|||
CAPath: b.stringVal(c.CAPath),
|
||||
CertFile: b.stringVal(c.CertFile),
|
||||
CheckUpdateInterval: b.durationVal("check_update_interval", c.CheckUpdateInterval),
|
||||
CheckOutputMaxSize: b.intValWithDefault(c.CheckOutputMaxSize, 4096),
|
||||
Checks: checks,
|
||||
ClientAddrs: clientAddrs,
|
||||
ConfigEntryBootstrap: configEntries,
|
||||
|
@ -880,6 +882,7 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
|||
TaggedAddresses: c.TaggedAddresses,
|
||||
TranslateWANAddrs: b.boolVal(c.TranslateWANAddrs),
|
||||
UIDir: b.stringVal(c.UIDir),
|
||||
UIContentPath: UIPathBuilder(b.stringVal(b.Flags.Config.UIContentPath)),
|
||||
UnixSocketGroup: b.stringVal(c.UnixSocket.Group),
|
||||
UnixSocketMode: b.stringVal(c.UnixSocket.Mode),
|
||||
UnixSocketUser: b.stringVal(c.UnixSocket.User),
|
||||
|
@ -905,6 +908,9 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
|||
// reDatacenter defines a regexp for a valid datacenter name
|
||||
var reDatacenter = regexp.MustCompile("^[a-z0-9_-]+$")
|
||||
|
||||
// validContentPath defines a regexp for a valid content path name.
|
||||
var validContentPath = regexp.MustCompile(`^[A-Za-z0-9/_-]+$`)
|
||||
var hasVersion = regexp.MustCompile(`^/v\d+/$`)
|
||||
// ----------------------------------------------------------------
|
||||
// check required params we cannot recover from first
|
||||
//
|
||||
|
@ -913,11 +919,20 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
|||
return fmt.Errorf("datacenter cannot be empty")
|
||||
}
|
||||
if !reDatacenter.MatchString(rt.Datacenter) {
|
||||
return fmt.Errorf("datacenter cannot be %q. Please use only [a-z0-9-_].", rt.Datacenter)
|
||||
return fmt.Errorf("datacenter cannot be %q. Please use only [a-z0-9-_]", rt.Datacenter)
|
||||
}
|
||||
if rt.DataDir == "" && !rt.DevMode {
|
||||
return fmt.Errorf("data_dir cannot be empty")
|
||||
}
|
||||
|
||||
if !validContentPath.MatchString(rt.UIContentPath) {
|
||||
return fmt.Errorf("ui-content-path can only contain alphanumeric, -, _, or /. received: %s", rt.UIContentPath)
|
||||
}
|
||||
|
||||
if hasVersion.MatchString(rt.UIContentPath) {
|
||||
return fmt.Errorf("ui-content-path cannot have 'v[0-9]'. received: %s", rt.UIContentPath)
|
||||
}
|
||||
|
||||
if !rt.DevMode {
|
||||
fi, err := os.Stat(rt.DataDir)
|
||||
switch {
|
||||
|
@ -964,6 +979,9 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
|||
if rt.BootstrapExpect > 0 && rt.Bootstrap {
|
||||
return fmt.Errorf("'bootstrap_expect > 0' and 'bootstrap = true' are mutually exclusive")
|
||||
}
|
||||
if rt.CheckOutputMaxSize < 1 {
|
||||
return fmt.Errorf("check_output_max_size must be positive, to discard check output use the discard_check_output flag")
|
||||
}
|
||||
if rt.AEInterval <= 0 {
|
||||
return fmt.Errorf("ae_interval cannot be %s. Must be positive", rt.AEInterval)
|
||||
}
|
||||
|
@ -971,7 +989,7 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
|
|||
return fmt.Errorf("autopilot.max_trailing_logs cannot be %d. Must be greater than or equal to zero", rt.AutopilotMaxTrailingLogs)
|
||||
}
|
||||
if rt.ACLDatacenter != "" && !reDatacenter.MatchString(rt.ACLDatacenter) {
|
||||
return fmt.Errorf("acl_datacenter cannot be %q. Please use only [a-z0-9-_].", rt.ACLDatacenter)
|
||||
return fmt.Errorf("acl_datacenter cannot be %q. Please use only [a-z0-9-_]", rt.ACLDatacenter)
|
||||
}
|
||||
if rt.EnableUI && rt.UIDir != "" {
|
||||
return fmt.Errorf(
|
||||
|
@ -1174,6 +1192,7 @@ func (b *Builder) checkVal(v *CheckDefinition) *structs.CheckDefinition {
|
|||
Timeout: b.durationVal(fmt.Sprintf("check[%s].timeout", id), v.Timeout),
|
||||
TTL: b.durationVal(fmt.Sprintf("check[%s].ttl", id), v.TTL),
|
||||
DeregisterCriticalServiceAfter: b.durationVal(fmt.Sprintf("check[%s].deregister_critical_service_after", id), v.DeregisterCriticalServiceAfter),
|
||||
OutputMaxSize: b.intValWithDefault(v.OutputMaxSize, checks.DefaultBufSize),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1368,13 +1387,17 @@ func (b *Builder) durationVal(name string, v *string) (d time.Duration) {
|
|||
return b.durationValWithDefault(name, v, 0)
|
||||
}
|
||||
|
||||
func (b *Builder) intVal(v *int) int {
|
||||
func (b *Builder) intValWithDefault(v *int, defaultVal int) int {
|
||||
if v == nil {
|
||||
return 0
|
||||
return defaultVal
|
||||
}
|
||||
return *v
|
||||
}
|
||||
|
||||
func (b *Builder) intVal(v *int) int {
|
||||
return b.intValWithDefault(v, 0)
|
||||
}
|
||||
|
||||
func (b *Builder) portVal(name string, v *int) int {
|
||||
if v == nil || *v <= 0 {
|
||||
return -1
|
||||
|
@ -1683,3 +1706,17 @@ func isUnixAddr(a net.Addr) bool {
|
|||
_, ok := a.(*net.UnixAddr)
|
||||
return ok
|
||||
}
|
||||
|
||||
// UIPathBuilder checks to see if there was a path set
|
||||
// If so, adds beginning and trailing slashes to UI path
|
||||
func UIPathBuilder(UIContentString string) string {
|
||||
if UIContentString != "" {
|
||||
var fmtedPath string
|
||||
fmtedPath = strings.Trim(UIContentString, "/")
|
||||
fmtedPath = "/" + fmtedPath + "/"
|
||||
return fmtedPath
|
||||
|
||||
}
|
||||
return "/ui/"
|
||||
|
||||
}
|
||||
|
|
|
@ -184,6 +184,7 @@ type Config struct {
|
|||
CAPath *string `json:"ca_path,omitempty" hcl:"ca_path" mapstructure:"ca_path"`
|
||||
CertFile *string `json:"cert_file,omitempty" hcl:"cert_file" mapstructure:"cert_file"`
|
||||
Check *CheckDefinition `json:"check,omitempty" hcl:"check" mapstructure:"check"` // needs to be a pointer to avoid partial merges
|
||||
CheckOutputMaxSize *int `json:"check_output_max_size,omitempty" hcl:"check_output_max_size" mapstructure:"check_output_max_size"`
|
||||
CheckUpdateInterval *string `json:"check_update_interval,omitempty" hcl:"check_update_interval" mapstructure:"check_update_interval"`
|
||||
Checks []CheckDefinition `json:"checks,omitempty" hcl:"checks" mapstructure:"checks"`
|
||||
ClientAddr *string `json:"client_addr,omitempty" hcl:"client_addr" mapstructure:"client_addr"`
|
||||
|
@ -264,6 +265,7 @@ type Config struct {
|
|||
Telemetry Telemetry `json:"telemetry,omitempty" hcl:"telemetry" mapstructure:"telemetry"`
|
||||
TranslateWANAddrs *bool `json:"translate_wan_addrs,omitempty" hcl:"translate_wan_addrs" mapstructure:"translate_wan_addrs"`
|
||||
UI *bool `json:"ui,omitempty" hcl:"ui" mapstructure:"ui"`
|
||||
UIContentPath *string `json:"ui_content_path,omitempty" hcl:"ui_content_path" mapstructure:"ui_content_path"`
|
||||
UIDir *string `json:"ui_dir,omitempty" hcl:"ui_dir" mapstructure:"ui_dir"`
|
||||
UnixSocket UnixSocket `json:"unix_sockets,omitempty" hcl:"unix_sockets" mapstructure:"unix_sockets"`
|
||||
VerifyIncoming *bool `json:"verify_incoming,omitempty" hcl:"verify_incoming" mapstructure:"verify_incoming"`
|
||||
|
@ -396,6 +398,7 @@ type CheckDefinition struct {
|
|||
HTTP *string `json:"http,omitempty" hcl:"http" mapstructure:"http"`
|
||||
Header map[string][]string `json:"header,omitempty" hcl:"header" mapstructure:"header"`
|
||||
Method *string `json:"method,omitempty" hcl:"method" mapstructure:"method"`
|
||||
OutputMaxSize *int `json:"output_max_size,omitempty" hcl:"output_max_size" mapstructure:"output_max_size"`
|
||||
TCP *string `json:"tcp,omitempty" hcl:"tcp" mapstructure:"tcp"`
|
||||
Interval *string `json:"interval,omitempty" hcl:"interval" mapstructure:"interval"`
|
||||
DockerContainerID *string `json:"docker_container_id,omitempty" hcl:"docker_container_id" mapstructure:"docker_container_id"`
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/consul"
|
||||
"github.com/hashicorp/consul/version"
|
||||
)
|
||||
|
@ -49,6 +50,7 @@ func DefaultSource() Source {
|
|||
bind_addr = "0.0.0.0"
|
||||
bootstrap = false
|
||||
bootstrap_expect = 0
|
||||
check_output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
check_update_interval = "5m"
|
||||
client_addr = "127.0.0.1"
|
||||
datacenter = "` + consul.DefaultDC + `"
|
||||
|
|
|
@ -60,6 +60,7 @@ func AddFlags(fs *flag.FlagSet, f *Flags) {
|
|||
add(&f.Config.Bootstrap, "bootstrap", "Sets server to bootstrap mode.")
|
||||
add(&f.Config.BootstrapExpect, "bootstrap-expect", "Sets server to expect bootstrap mode.")
|
||||
add(&f.Config.ClientAddr, "client", "Sets the address to bind for client access. This includes RPC, DNS, HTTP, HTTPS and gRPC (if configured).")
|
||||
add(&f.Config.CheckOutputMaxSize, "check_output_max_size", "Sets the maximum output size for checks on this agent")
|
||||
add(&f.ConfigFiles, "config-dir", "Path to a directory to read configuration files from. This will read every file ending in '.json' as configuration in this directory in alphabetical order. Can be specified multiple times.")
|
||||
add(&f.ConfigFiles, "config-file", "Path to a file in JSON or HCL format with a matching file extension. Can be specified multiple times.")
|
||||
add(&f.ConfigFormat, "config-format", "Config files are in this format irrespective of their extension. Must be 'hcl' or 'json'")
|
||||
|
@ -105,6 +106,7 @@ func AddFlags(fs *flag.FlagSet, f *Flags) {
|
|||
add(&f.Config.ServerMode, "server", "Switches agent to server mode.")
|
||||
add(&f.Config.EnableSyslog, "syslog", "Enables logging to syslog.")
|
||||
add(&f.Config.UI, "ui", "Enables the built-in static web UI server.")
|
||||
add(&f.Config.UIContentPath, "ui-content-path", "Sets the external UI path to a string. Defaults to: /ui/ ")
|
||||
add(&f.Config.UIDir, "ui-dir", "Path to directory containing the web UI resources.")
|
||||
add(&f.HCL, "hcl", "hcl config fragment. Can be specified multiple times.")
|
||||
}
|
||||
|
|
|
@ -459,6 +459,11 @@ type RuntimeConfig struct {
|
|||
// hcl: check_update_interval = "duration"
|
||||
CheckUpdateInterval time.Duration
|
||||
|
||||
// Maximum size for the output of a healtcheck
|
||||
// hcl check_output_max_size int
|
||||
// flag: -check_output_max_size int
|
||||
CheckOutputMaxSize int
|
||||
|
||||
// Checks contains the provided check definitions.
|
||||
//
|
||||
// hcl: checks = [
|
||||
|
@ -1382,6 +1387,10 @@ type RuntimeConfig struct {
|
|||
// flag: -ui-dir string
|
||||
UIDir string
|
||||
|
||||
//UIContentPath is a string that sets the external
|
||||
// path to a string. Default: /ui/
|
||||
UIContentPath string
|
||||
|
||||
// UnixSocketGroup contains the group of the file permissions when
|
||||
// Consul binds to UNIX sockets.
|
||||
//
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
|
@ -742,6 +743,18 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
rt.DataDir = dataDir
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "-ui-content-path",
|
||||
args: []string{
|
||||
`-ui-content-path=/a/b`,
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
|
||||
patch: func(rt *RuntimeConfig) {
|
||||
rt.UIContentPath = "/a/b/"
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ports and addresses
|
||||
|
@ -2076,8 +2089,8 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
},
|
||||
patch: func(rt *RuntimeConfig) {
|
||||
rt.Checks = []*structs.CheckDefinition{
|
||||
&structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}},
|
||||
&structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}},
|
||||
&structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}, OutputMaxSize: checks.DefaultBufSize},
|
||||
&structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}, OutputMaxSize: checks.DefaultBufSize},
|
||||
}
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
|
@ -2095,7 +2108,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
},
|
||||
patch: func(rt *RuntimeConfig) {
|
||||
rt.Checks = []*structs.CheckDefinition{
|
||||
&structs.CheckDefinition{Name: "a", GRPC: "localhost:12345/foo", GRPCUseTLS: true},
|
||||
&structs.CheckDefinition{Name: "a", GRPC: "localhost:12345/foo", GRPCUseTLS: true, OutputMaxSize: checks.DefaultBufSize},
|
||||
}
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
|
@ -2113,7 +2126,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
},
|
||||
patch: func(rt *RuntimeConfig) {
|
||||
rt.Checks = []*structs.CheckDefinition{
|
||||
&structs.CheckDefinition{Name: "a", AliasService: "foo"},
|
||||
&structs.CheckDefinition{Name: "a", AliasService: "foo", OutputMaxSize: checks.DefaultBufSize},
|
||||
}
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
|
@ -2250,6 +2263,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
DockerContainerID: "z",
|
||||
DeregisterCriticalServiceAfter: 10 * time.Second,
|
||||
ScriptArgs: []string{"a", "b"},
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
},
|
||||
},
|
||||
Weights: &structs.Weights{
|
||||
|
@ -2515,8 +2529,9 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
Port: 2345,
|
||||
Checks: structs.CheckTypes{
|
||||
{
|
||||
TCP: "127.0.0.1:2345",
|
||||
Interval: 10 * time.Second,
|
||||
TCP: "127.0.0.1:2345",
|
||||
Interval: 10 * time.Second,
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
},
|
||||
},
|
||||
Proxy: &structs.ConnectProxyConfig{
|
||||
|
@ -2610,8 +2625,9 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
|||
Port: 2345,
|
||||
Checks: structs.CheckTypes{
|
||||
{
|
||||
TCP: "127.0.0.1:2345",
|
||||
Interval: 10 * time.Second,
|
||||
TCP: "127.0.0.1:2345",
|
||||
Interval: 10 * time.Second,
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
},
|
||||
},
|
||||
Proxy: &structs.ConnectProxyConfig{
|
||||
|
@ -3043,6 +3059,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"f3r6xFtM": [ "RyuIdDWv", "QbxEcIUM" ]
|
||||
},
|
||||
"method": "Dou0nGT5",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"tcp": "JY6fTTcw",
|
||||
"interval": "18714s",
|
||||
"docker_container_id": "qF66POS9",
|
||||
|
@ -3069,6 +3086,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "aldrIQ4l",
|
||||
"tcp": "RJQND605",
|
||||
"interval": "22164s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "ipgdFtjd",
|
||||
"shell": "qAeOYy0M",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3092,6 +3110,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "gLrztrNw",
|
||||
"tcp": "4jG5casb",
|
||||
"interval": "28767s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "THW6u7rL",
|
||||
"shell": "C1Zt3Zwh",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3302,6 +3321,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "9afLm3Mj",
|
||||
"tcp": "fjiLFqVd",
|
||||
"interval": "23926s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "dO5TtRHk",
|
||||
"shell": "e6q2ttES",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3324,6 +3344,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "T66MFBfR",
|
||||
"tcp": "bNnNfx2A",
|
||||
"interval": "22224s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "ipgdFtjd",
|
||||
"shell": "omVZq7Sz",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3345,6 +3366,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "ciYHWors",
|
||||
"tcp": "FfvCwlqH",
|
||||
"interval": "12356s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "HBndBU6R",
|
||||
"shell": "hVI33JjA",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3380,6 +3402,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "X5DrovFc",
|
||||
"tcp": "ICbxkpSF",
|
||||
"interval": "24392s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "ZKXr68Yb",
|
||||
"shell": "CEfzx0Fo",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3418,6 +3441,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "5wkAxCUE",
|
||||
"tcp": "MN3oA9D2",
|
||||
"interval": "32718s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "cU15LMet",
|
||||
"shell": "nEz9qz2l",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3439,6 +3463,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"method": "wzByP903",
|
||||
"tcp": "2exjZIGE",
|
||||
"interval": "5656s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"docker_container_id": "5tDBWpfA",
|
||||
"shell": "rlTpLM8s",
|
||||
"tls_skip_verify": true,
|
||||
|
@ -3621,6 +3646,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "Dou0nGT5"
|
||||
tcp = "JY6fTTcw"
|
||||
interval = "18714s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "qF66POS9"
|
||||
shell = "sOnDy228"
|
||||
tls_skip_verify = true
|
||||
|
@ -3645,6 +3671,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "aldrIQ4l"
|
||||
tcp = "RJQND605"
|
||||
interval = "22164s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "ipgdFtjd"
|
||||
shell = "qAeOYy0M"
|
||||
tls_skip_verify = true
|
||||
|
@ -3668,6 +3695,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "gLrztrNw"
|
||||
tcp = "4jG5casb"
|
||||
interval = "28767s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "THW6u7rL"
|
||||
shell = "C1Zt3Zwh"
|
||||
tls_skip_verify = true
|
||||
|
@ -3903,6 +3931,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "T66MFBfR"
|
||||
tcp = "bNnNfx2A"
|
||||
interval = "22224s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "ipgdFtjd"
|
||||
shell = "omVZq7Sz"
|
||||
tls_skip_verify = true
|
||||
|
@ -3924,6 +3953,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "ciYHWors"
|
||||
tcp = "FfvCwlqH"
|
||||
interval = "12356s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "HBndBU6R"
|
||||
shell = "hVI33JjA"
|
||||
tls_skip_verify = true
|
||||
|
@ -3959,6 +3989,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "X5DrovFc"
|
||||
tcp = "ICbxkpSF"
|
||||
interval = "24392s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "ZKXr68Yb"
|
||||
shell = "CEfzx0Fo"
|
||||
tls_skip_verify = true
|
||||
|
@ -3997,6 +4028,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "5wkAxCUE"
|
||||
tcp = "MN3oA9D2"
|
||||
interval = "32718s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "cU15LMet"
|
||||
shell = "nEz9qz2l"
|
||||
tls_skip_verify = true
|
||||
|
@ -4018,6 +4050,7 @@ func TestFullConfig(t *testing.T) {
|
|||
method = "wzByP903"
|
||||
tcp = "2exjZIGE"
|
||||
interval = "5656s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
docker_container_id = "5tDBWpfA"
|
||||
shell = "rlTpLM8s"
|
||||
tls_skip_verify = true
|
||||
|
@ -4286,6 +4319,7 @@ func TestFullConfig(t *testing.T) {
|
|||
CAFile: "erA7T0PM",
|
||||
CAPath: "mQEN1Mfp",
|
||||
CertFile: "7s4QAzDk",
|
||||
CheckOutputMaxSize: checks.DefaultBufSize,
|
||||
Checks: []*structs.CheckDefinition{
|
||||
&structs.CheckDefinition{
|
||||
ID: "uAjE6m9Z",
|
||||
|
@ -4303,6 +4337,7 @@ func TestFullConfig(t *testing.T) {
|
|||
Method: "aldrIQ4l",
|
||||
TCP: "RJQND605",
|
||||
Interval: 22164 * time.Second,
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
DockerContainerID: "ipgdFtjd",
|
||||
Shell: "qAeOYy0M",
|
||||
TLSSkipVerify: true,
|
||||
|
@ -4324,6 +4359,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"qxvdnSE9": []string{"6wBPUYdF", "YYh8wtSZ"},
|
||||
},
|
||||
Method: "gLrztrNw",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "4jG5casb",
|
||||
Interval: 28767 * time.Second,
|
||||
DockerContainerID: "THW6u7rL",
|
||||
|
@ -4347,6 +4383,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"f3r6xFtM": {"RyuIdDWv", "QbxEcIUM"},
|
||||
},
|
||||
Method: "Dou0nGT5",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "JY6fTTcw",
|
||||
Interval: 18714 * time.Second,
|
||||
DockerContainerID: "qF66POS9",
|
||||
|
@ -4515,6 +4552,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"cVFpko4u": {"gGqdEB6k", "9LsRo22u"},
|
||||
},
|
||||
Method: "X5DrovFc",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "ICbxkpSF",
|
||||
Interval: 24392 * time.Second,
|
||||
DockerContainerID: "ZKXr68Yb",
|
||||
|
@ -4563,6 +4601,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"1UJXjVrT": {"OJgxzTfk", "xZZrFsq7"},
|
||||
},
|
||||
Method: "5wkAxCUE",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "MN3oA9D2",
|
||||
Interval: 32718 * time.Second,
|
||||
DockerContainerID: "cU15LMet",
|
||||
|
@ -4584,6 +4623,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"vr7wY7CS": {"EtCoNPPL", "9vAarJ5s"},
|
||||
},
|
||||
Method: "wzByP903",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "2exjZIGE",
|
||||
Interval: 5656 * time.Second,
|
||||
DockerContainerID: "5tDBWpfA",
|
||||
|
@ -4679,6 +4719,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"SHOVq1Vv": {"jntFhyym", "GYJh32pp"},
|
||||
},
|
||||
Method: "T66MFBfR",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "bNnNfx2A",
|
||||
Interval: 22224 * time.Second,
|
||||
DockerContainerID: "ipgdFtjd",
|
||||
|
@ -4700,6 +4741,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"p2UI34Qz": {"UsG1D0Qh", "NHhRiB6s"},
|
||||
},
|
||||
Method: "ciYHWors",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "FfvCwlqH",
|
||||
Interval: 12356 * time.Second,
|
||||
DockerContainerID: "HBndBU6R",
|
||||
|
@ -4721,6 +4763,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"l4HwQ112": {"fk56MNlo", "dhLK56aZ"},
|
||||
},
|
||||
Method: "9afLm3Mj",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "fjiLFqVd",
|
||||
Interval: 23926 * time.Second,
|
||||
DockerContainerID: "dO5TtRHk",
|
||||
|
@ -4777,6 +4820,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"wan": "78.63.37.19",
|
||||
},
|
||||
TranslateWANAddrs: true,
|
||||
UIContentPath: "/ui/",
|
||||
UIDir: "11IFzAUn",
|
||||
UnixSocketUser: "E0nB1DwA",
|
||||
UnixSocketGroup: "8pFodrV8",
|
||||
|
@ -5058,6 +5102,7 @@ func TestConfigDecodeBytes(t *testing.T) {
|
|||
func TestSanitize(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
BindAddr: &net.IPAddr{IP: net.ParseIP("127.0.0.1")},
|
||||
CheckOutputMaxSize: checks.DefaultBufSize,
|
||||
SerfAdvertiseAddrLAN: &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678},
|
||||
DNSAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678},
|
||||
|
@ -5080,7 +5125,8 @@ func TestSanitize(t *testing.T) {
|
|||
Name: "foo",
|
||||
Token: "bar",
|
||||
Check: structs.CheckType{
|
||||
Name: "blurb",
|
||||
Name: "blurb",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
},
|
||||
Weights: &structs.Weights{
|
||||
Passing: 67,
|
||||
|
@ -5090,8 +5136,9 @@ func TestSanitize(t *testing.T) {
|
|||
},
|
||||
Checks: []*structs.CheckDefinition{
|
||||
&structs.CheckDefinition{
|
||||
Name: "zoo",
|
||||
Token: "zope",
|
||||
Name: "zoo",
|
||||
Token: "zope",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -5131,6 +5178,7 @@ func TestSanitize(t *testing.T) {
|
|||
"CAPath": "",
|
||||
"CertFile": "",
|
||||
"CheckDeregisterIntervalMin": "0s",
|
||||
"CheckOutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"CheckReapInterval": "0s",
|
||||
"CheckUpdateInterval": "0s",
|
||||
"Checks": [{
|
||||
|
@ -5147,6 +5195,7 @@ func TestSanitize(t *testing.T) {
|
|||
"Method": "",
|
||||
"Name": "zoo",
|
||||
"Notes": "",
|
||||
"OutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"ScriptArgs": [],
|
||||
"ServiceID": "",
|
||||
"Shell": "",
|
||||
|
@ -5178,6 +5227,7 @@ func TestSanitize(t *testing.T) {
|
|||
"ConsulCoordinateUpdateMaxBatches": 0,
|
||||
"ConsulCoordinateUpdatePeriod": "15s",
|
||||
"ConsulRaftElectionTimeout": "0s",
|
||||
"CheckOutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"ConsulRaftHeartbeatTimeout": "0s",
|
||||
"ConsulRaftLeaderLeaseTimeout": "0s",
|
||||
"GossipLANGossipInterval": "0s",
|
||||
|
@ -5317,6 +5367,7 @@ func TestSanitize(t *testing.T) {
|
|||
"Method": "",
|
||||
"Name": "blurb",
|
||||
"Notes": "",
|
||||
"OutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"ScriptArgs": [],
|
||||
"Shell": "",
|
||||
"Status": "",
|
||||
|
@ -5380,6 +5431,7 @@ func TestSanitize(t *testing.T) {
|
|||
"StatsiteAddr": ""
|
||||
},
|
||||
"TranslateWANAddrs": false,
|
||||
"UIContentPath": "",
|
||||
"UIDir": "",
|
||||
"UnixSocketGroup": "",
|
||||
"UnixSocketMode": "",
|
||||
|
@ -5720,6 +5772,41 @@ func TestReadPath(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_UIPathBuilder(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
path string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"Letters only string",
|
||||
"hello",
|
||||
"/hello/",
|
||||
},
|
||||
{
|
||||
"Alphanumeric",
|
||||
"Hello1",
|
||||
"/Hello1/",
|
||||
},
|
||||
{
|
||||
"Hyphen and underscore",
|
||||
"-_",
|
||||
"/-_/",
|
||||
},
|
||||
{
|
||||
"Many slashes",
|
||||
"/hello/ui/1/",
|
||||
"/hello/ui/1/",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
actual := UIPathBuilder(tt.path)
|
||||
require.Equal(t, tt.expected, actual)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func splitIPPort(hostport string) (net.IP, int) {
|
||||
h, p, err := net.SplitHostPort(hostport)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/consul/autopilot"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
|
@ -368,6 +369,9 @@ type Config struct {
|
|||
// warning and discard the remaining updates.
|
||||
CoordinateUpdateMaxBatches int
|
||||
|
||||
// CheckOutputMaxSize control the max size of output of checks
|
||||
CheckOutputMaxSize int
|
||||
|
||||
// RPCHoldTimeout is how long an RPC can be "held" before it is errored.
|
||||
// This is used to paper over a loss of leadership by instead holding RPCs,
|
||||
// so that the caller experiences a slow response rather than an error.
|
||||
|
@ -502,6 +506,8 @@ func DefaultConfig() *Config {
|
|||
CoordinateUpdateBatchSize: 128,
|
||||
CoordinateUpdateMaxBatches: 5,
|
||||
|
||||
CheckOutputMaxSize: checks.DefaultBufSize,
|
||||
|
||||
RPCRate: rate.Inf,
|
||||
RPCMaxBurst: 1000,
|
||||
|
||||
|
|
|
@ -1363,6 +1363,17 @@ func (s *Server) handleAliveMember(member serf.Member) error {
|
|||
ID: structs.ConsulServiceID,
|
||||
Service: structs.ConsulServiceName,
|
||||
Port: parts.Port,
|
||||
Weights: &structs.Weights{
|
||||
Passing: 1,
|
||||
Warning: 1,
|
||||
},
|
||||
Meta: map[string]string{
|
||||
"raft_version": strconv.Itoa(parts.RaftVersion),
|
||||
"serf_protocol_current": strconv.FormatUint(uint64(member.ProtocolCur), 10),
|
||||
"serf_protocol_min": strconv.FormatUint(uint64(member.ProtocolMin), 10),
|
||||
"serf_protocol_max": strconv.FormatUint(uint64(member.ProtocolMax), 10),
|
||||
"version": parts.Build.String(),
|
||||
},
|
||||
}
|
||||
|
||||
// Attempt to join the consul server
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/NYTimes/gziphandler"
|
||||
|
@ -83,6 +87,66 @@ type HTTPServer struct {
|
|||
// proto is filled by the agent to "http" or "https".
|
||||
proto string
|
||||
}
|
||||
type templatedFile struct {
|
||||
templated *bytes.Reader
|
||||
name string
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func newTemplatedFile(buf *bytes.Buffer, raw http.File) *templatedFile {
|
||||
info, _ := raw.Stat()
|
||||
return &templatedFile{
|
||||
templated: bytes.NewReader(buf.Bytes()),
|
||||
name: info.Name(),
|
||||
mode: info.Mode(),
|
||||
modTime: info.ModTime(),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *templatedFile) Read(p []byte) (n int, err error) {
|
||||
return t.templated.Read(p)
|
||||
}
|
||||
|
||||
func (t *templatedFile) Seek(offset int64, whence int) (int64, error) {
|
||||
return t.templated.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (t *templatedFile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *templatedFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||
return nil, errors.New("not a directory")
|
||||
}
|
||||
|
||||
func (t *templatedFile) Stat() (os.FileInfo, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *templatedFile) Name() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *templatedFile) Size() int64 {
|
||||
return int64(t.templated.Len())
|
||||
}
|
||||
|
||||
func (t *templatedFile) Mode() os.FileMode {
|
||||
return t.mode
|
||||
}
|
||||
|
||||
func (t *templatedFile) ModTime() time.Time {
|
||||
return t.modTime
|
||||
}
|
||||
|
||||
func (t *templatedFile) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *templatedFile) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
type redirectFS struct {
|
||||
fs http.FileSystem
|
||||
|
@ -96,6 +160,25 @@ func (fs *redirectFS) Open(name string) (http.File, error) {
|
|||
return file, err
|
||||
}
|
||||
|
||||
type templatedIndexFS struct {
|
||||
fs http.FileSystem
|
||||
ContentPath string
|
||||
}
|
||||
|
||||
func (fs *templatedIndexFS) Open(name string) (http.File, error) {
|
||||
file, err := fs.fs.Open(name)
|
||||
if err == nil && name == "/index.html" {
|
||||
content, _ := ioutil.ReadAll(file)
|
||||
file.Seek(0, 0)
|
||||
t, _ := template.New("fmtedindex").Parse(string(content))
|
||||
var out bytes.Buffer
|
||||
err = t.Execute(&out, fs)
|
||||
file = newTemplatedFile(&out, file)
|
||||
}
|
||||
|
||||
return file, err
|
||||
}
|
||||
|
||||
// endpoint is a Consul-specific HTTP handler that takes the usual arguments in
|
||||
// but returns a response object and error, both of which are handled in a
|
||||
// common manner by Consul's HTTP server.
|
||||
|
@ -207,7 +290,6 @@ func (s *HTTPServer) handler(enableDebug bool) http.Handler {
|
|||
|
||||
handleFuncMetrics(pattern, http.HandlerFunc(wrapper))
|
||||
}
|
||||
|
||||
mux.HandleFunc("/", s.Index)
|
||||
for pattern, fn := range endpoints {
|
||||
thisFn := fn
|
||||
|
@ -227,7 +309,6 @@ func (s *HTTPServer) handler(enableDebug bool) http.Handler {
|
|||
|
||||
if s.IsUIEnabled() {
|
||||
var uifs http.FileSystem
|
||||
|
||||
// Use the custom UI dir if provided.
|
||||
if s.agent.config.UIDir != "" {
|
||||
uifs = http.Dir(s.agent.config.UIDir)
|
||||
|
@ -235,10 +316,9 @@ func (s *HTTPServer) handler(enableDebug bool) http.Handler {
|
|||
fs := assetFS()
|
||||
uifs = fs
|
||||
}
|
||||
uifs = &redirectFS{fs: uifs}
|
||||
|
||||
uifs = &redirectFS{fs: &templatedIndexFS{fs: uifs, ContentPath: s.agent.config.UIContentPath}}
|
||||
mux.Handle("/robots.txt", http.FileServer(uifs))
|
||||
mux.Handle("/ui/", http.StripPrefix("/ui/", http.FileServer(uifs)))
|
||||
mux.Handle(s.agent.config.UIContentPath, http.StripPrefix(s.agent.config.UIContentPath, http.FileServer(uifs)))
|
||||
}
|
||||
|
||||
// Wrap the whole mux with a handler that bans URLs with non-printable
|
||||
|
@ -489,7 +569,7 @@ func (s *HTTPServer) Index(resp http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// Redirect to the UI endpoint
|
||||
http.Redirect(resp, req, "/ui/", http.StatusMovedPermanently) // 301
|
||||
http.Redirect(resp, req, s.agent.config.UIContentPath, http.StatusMovedPermanently) // 301
|
||||
}
|
||||
|
||||
// decodeBody is used to decode a JSON request body
|
||||
|
|
|
@ -37,6 +37,7 @@ type CheckDefinition struct {
|
|||
Timeout time.Duration
|
||||
TTL time.Duration
|
||||
DeregisterCriticalServiceAfter time.Duration
|
||||
OutputMaxSize int
|
||||
}
|
||||
|
||||
func (c *CheckDefinition) HealthCheck(node string) *HealthCheck {
|
||||
|
@ -72,6 +73,7 @@ func (c *CheckDefinition) CheckType() *CheckType {
|
|||
GRPCUseTLS: c.GRPCUseTLS,
|
||||
Header: c.Header,
|
||||
Method: c.Method,
|
||||
OutputMaxSize: c.OutputMaxSize,
|
||||
TCP: c.TCP,
|
||||
Interval: c.Interval,
|
||||
DockerContainerID: c.DockerContainerID,
|
||||
|
|
|
@ -45,6 +45,7 @@ type CheckType struct {
|
|||
// service, if any, to be deregistered if this check is critical for
|
||||
// longer than this duration.
|
||||
DeregisterCriticalServiceAfter time.Duration
|
||||
OutputMaxSize int
|
||||
}
|
||||
type CheckTypes []*CheckType
|
||||
|
||||
|
@ -67,6 +68,9 @@ func (c *CheckType) Validate() error {
|
|||
if !intervalCheck && !c.IsAlias() && c.TTL <= 0 {
|
||||
return fmt.Errorf("TTL must be > 0 for TTL checks")
|
||||
}
|
||||
if c.OutputMaxSize < 0 {
|
||||
return fmt.Errorf("MaxOutputMaxSize must be positive")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -999,6 +999,7 @@ type HealthCheckDefinition struct {
|
|||
Method string `json:",omitempty"`
|
||||
TCP string `json:",omitempty"`
|
||||
Interval time.Duration `json:",omitempty"`
|
||||
OutputMaxSize uint `json:",omitempty"`
|
||||
Timeout time.Duration `json:",omitempty"`
|
||||
DeregisterCriticalServiceAfter time.Duration `json:",omitempty"`
|
||||
}
|
||||
|
@ -1007,11 +1008,13 @@ func (d *HealthCheckDefinition) MarshalJSON() ([]byte, error) {
|
|||
type Alias HealthCheckDefinition
|
||||
exported := &struct {
|
||||
Interval string `json:",omitempty"`
|
||||
OutputMaxSize uint `json:",omitempty"`
|
||||
Timeout string `json:",omitempty"`
|
||||
DeregisterCriticalServiceAfter string `json:",omitempty"`
|
||||
*Alias
|
||||
}{
|
||||
Interval: d.Interval.String(),
|
||||
OutputMaxSize: d.OutputMaxSize,
|
||||
Timeout: d.Timeout.String(),
|
||||
DeregisterCriticalServiceAfter: d.DeregisterCriticalServiceAfter.String(),
|
||||
Alias: (*Alias)(d),
|
||||
|
|
|
@ -974,7 +974,7 @@ function ui_version {
|
|||
return 1
|
||||
fi
|
||||
|
||||
local ui_version="$(grep '<!-- CONSUL_VERSION: .* -->$' "$1" | sed 's/^<!-- CONSUL_VERSION: \(.*\) -->$/\1/')" || return 1
|
||||
local ui_version="$(grep '<!-- CONSUL_VERSION: .* -->' "$1" | sed 's/<!-- CONSUL_VERSION: \(.*\) -->/\1/' | xargs)" || return 1
|
||||
echo "$ui_version"
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -2,7 +2,13 @@ ROOT:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
|||
|
||||
all: build
|
||||
|
||||
deps: node_modules
|
||||
deps: node_modules clean
|
||||
|
||||
clean:
|
||||
rm -rf ./tmp
|
||||
|
||||
build-ci: deps
|
||||
yarn run build-ci --output-path=dist
|
||||
|
||||
build: deps
|
||||
yarn run build
|
||||
|
@ -19,6 +25,9 @@ test: deps
|
|||
test-view: deps
|
||||
yarn run test:view
|
||||
|
||||
test-parallel: deps
|
||||
yarn test-parallel
|
||||
|
||||
lint: deps
|
||||
yarn run lint:js
|
||||
|
||||
|
@ -31,4 +40,4 @@ steps:
|
|||
node_modules: yarn.lock package.json
|
||||
yarn install
|
||||
|
||||
.PHONY: all deps build start test test-view lint format
|
||||
.PHONY: all deps build start test test-view lint format clean
|
||||
|
|
|
@ -6,51 +6,12 @@
|
|||
<title>Consul by HashiCorp</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{{content-for "// all HTML content is populated via ./lib/startup/index"}}
|
||||
{{content-for "head"}}
|
||||
<link rel="icon" type="image/png" href="{{rootURL}}assets/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="{{rootURL}}assets/favicon-16x16.png" sizes="16x16">
|
||||
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/consul-ui.css">
|
||||
|
||||
{{content-for "head-footer"}}
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div style="margin: 0 auto;">
|
||||
<h2>JavaScript Required</h2>
|
||||
<p>Please enable JavaScript in your web browser to use Consul UI.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
{{content-for "body"}}
|
||||
<script src="{{rootURL}}assets/vendor.js"></script>
|
||||
<script>
|
||||
var appendScript = function(src) {
|
||||
var $script = document.createElement('script');
|
||||
$script.src = src;
|
||||
document.body.appendChild($script);
|
||||
}
|
||||
if(!('TextDecoder' in window)) {
|
||||
appendScript('{{rootURL}}assets/encoding-indexes.js');
|
||||
appendScript('{{rootURL}}assets/encoding.js');
|
||||
}
|
||||
</script>
|
||||
<script src="{{rootURL}}assets/consul-ui.js"></script>
|
||||
<script>
|
||||
CodeMirror.modeURL = {
|
||||
replace: function(n, mode) {
|
||||
switch(mode) {
|
||||
case 'javascript':
|
||||
return '{{rootURL}}assets/codemirror/mode/javascript/javascript.js';
|
||||
case 'ruby':
|
||||
return '{{rootURL}}assets/codemirror/mode/ruby/ruby.js';
|
||||
case 'yaml':
|
||||
return '{{rootURL}}assets/codemirror/mode/yaml/yaml.js';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
{{content-for "body-footer"}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
module.exports = {
|
||||
name: 'startup',
|
||||
contentFor: function(type, config) {
|
||||
const enterprise = config.CONSUL_BINARY_TYPE !== 'oss' && config.CONSUL_BINARY_TYPE !== '';
|
||||
const vars = {
|
||||
appName: config.modulePrefix,
|
||||
environment: config.environment,
|
||||
rootURL: config.environment === 'production' ? '{{.ContentPath}}' : config.rootURL,
|
||||
config: config,
|
||||
};
|
||||
switch (type) {
|
||||
case 'head':
|
||||
return `<!-- CONSUL_VERSION: ${config.CONSUL_VERSION} -->`;
|
||||
return require('./templates/head.html.js')(vars);
|
||||
case 'body':
|
||||
return `<svg width="168" height="53" xmlns="http://www.w3.org/2000/svg"><g fill="#919FA8" fill-rule="evenodd"><path d="M26.078 32.12a5.586 5.586 0 1 1 5.577-5.599 5.577 5.577 0 0 1-5.577 5.6M37.009 29.328a2.56 2.56 0 1 1 2.56-2.56 2.551 2.551 0 0 1-2.56 2.56M46.916 31.669a2.56 2.56 0 1 1 .051-.21c-.028.066-.028.13-.051.21M44.588 25.068a2.565 2.565 0 0 1-2.672-.992 2.558 2.558 0 0 1-.102-2.845 2.564 2.564 0 0 1 4.676.764c.072.328.081.667.027 1a2.463 2.463 0 0 1-1.925 2.073M53.932 31.402a2.547 2.547 0 0 1-2.95 2.076 2.559 2.559 0 0 1-2.064-2.965 2.547 2.547 0 0 1 2.948-2.077 2.57 2.57 0 0 1 2.128 2.716.664.664 0 0 0-.05.228M51.857 25.103a2.56 2.56 0 1 1 2.108-2.945c.034.218.043.439.027.658a2.547 2.547 0 0 1-2.135 2.287M49.954 40.113a2.56 2.56 0 1 1 .314-1.037c-.02.366-.128.721-.314 1.037M48.974 16.893a2.56 2.56 0 1 1 .97-3.487c.264.446.375.965.317 1.479a2.56 2.56 0 0 1-1.287 2.008"/><path d="M26.526 52.603c-14.393 0-26.06-11.567-26.06-25.836C.466 12.498 12.133.931 26.526.931a25.936 25.936 0 0 1 15.836 5.307l-3.167 4.117A20.962 20.962 0 0 0 17.304 8.23C10.194 11.713 5.7 18.9 5.714 26.763c-.014 7.862 4.48 15.05 11.59 18.534a20.962 20.962 0 0 0 21.89-2.127l3.168 4.123a25.981 25.981 0 0 1-15.836 5.31z"/>${
|
||||
enterprise
|
||||
? `<path data-enterprise-logo d="M61 42.083h3.975v.785H61.87v2.136h2.882v.784H61.87v2.31h3.114v.785H61v-6.8zm6.907 1.018V48.9h-.828v-6.817h1.2l2.94 5.84v-5.84h.829V48.9h-1.193L67.907 43.1zm7.826-.225h-2.012v-.784h4.911v.784h-2.02V48.9h-.879v-6.024zm4.564-.793h3.975v.785h-3.106v2.136h2.882v.784h-2.882v2.31h3.114v.785h-3.992l.009-6.8zm8.605 4.347h-1.657v2.503h-.87v-6.85h2.576c1.45 0 1.963.635 1.963 1.67v.984a1.435 1.435 0 0 1-1.077 1.585l1.756 2.57h-1.002l-1.69-2.462zm0-3.562h-1.657v2.778h1.657c.828 0 1.118-.234 1.118-.901v-.968c.024-.676-.265-.901-1.094-.901l-.024-.008zm4.488-.785h2.485c1.45 0 1.963.635 1.963 1.67v1.009c0 1.05-.505 1.668-1.963 1.668H94.3v2.47h-.87l-.04-6.817zm2.419.785h-1.54v2.803h1.54c.828 0 1.118-.234 1.118-.901v-1.001c0-.668-.282-.893-1.118-.893v-.008zm6.368 3.562h-1.656v2.503h-.87v-6.85h2.576c1.45 0 1.963.635 1.963 1.67v.984a1.435 1.435 0 0 1-1.077 1.585l1.756 2.57h-1.002l-1.69-2.462zm0-3.562h-1.656v2.778h1.656c.829 0 1.118-.234 1.118-.901v-.968c.017-.676-.265-.901-1.101-.901l-.017-.008zm5.392 6.032h-.828v-6.817h.828V48.9zm4.14.1a5.76 5.76 0 0 1-2.012-.359l.141-.717c.605.195 1.236.3 1.872.308 1.085 0 1.308-.283 1.308-1.06 0-.917 0-1-1.4-1.317-1.656-.368-1.83-.685-1.83-2.095 0-1.184.49-1.76 2.162-1.76a7.648 7.648 0 0 1 1.83.225l-.074.743a8.223 8.223 0 0 0-1.74-.192c-1.11 0-1.308.225-1.308 1.01 0 .942 0 .984 1.342 1.318 1.797.45 1.888.717 1.888 2.044.033 1.176-.315 1.852-2.178 1.852zm4.332-6.917h3.95v.785h-3.105v2.136h2.882v.784h-2.882v2.31H120v.785h-3.992l.033-6.8z" fill-rule="nonzero"/>`
|
||||
: ''
|
||||
}<path d="M61 30.15V17.948c0-4.962 2.845-7.85 9.495-7.85 2.484 0 5.048.326 7.252.895l-.561 4.433c-2.164-.406-4.688-.691-6.53-.691-3.486 0-4.608 1.22-4.608 4.108v10.412c0 2.888 1.122 4.108 4.607 4.108 1.843 0 4.367-.284 6.53-.691l.562 4.433c-2.204.57-4.768.895-7.252.895C63.845 38 61 35.112 61 30.15zm36.808.04c0 4.068-1.802 7.81-8.493 7.81-6.69 0-8.494-3.742-8.494-7.81v-5.002c0-4.067 1.803-7.81 8.494-7.81 6.69 0 8.493 3.743 8.493 7.81v5.003zm-4.887-5.165c0-2.237-1.002-3.416-3.606-3.416s-3.606 1.18-3.606 3.416v5.328c0 2.237 1.002 3.417 3.606 3.417s3.606-1.18 3.606-3.417v-5.328zm25.79 12.568h-4.887V23.764c0-1.057-.44-1.586-1.563-1.586-1.201 0-3.325.732-5.088 1.668v13.747h-4.887V17.785h3.726l.48 1.668c2.444-1.22 5.53-2.074 7.813-2.074 3.245 0 4.407 2.318 4.407 5.857v14.357zm18.26-5.775c0 3.823-1.162 6.182-7.052 6.182-2.083 0-4.927-.488-6.73-1.139l.68-3.782c1.643.488 3.807.854 5.81.854 2.164 0 2.484-.488 2.484-1.993 0-1.22-.24-1.83-3.405-2.603-4.768-1.18-5.329-2.4-5.329-6.223 0-3.986 1.723-5.735 7.292-5.735 1.803 0 4.166.244 5.85.691l-.482 3.945c-1.482-.284-3.846-.569-5.368-.569-2.124 0-2.484.488-2.484 1.708 0 1.587.12 1.709 2.764 2.4 5.449 1.464 5.97 2.196 5.97 6.264zm4.357-14.033h4.887v13.83c0 1.057.441 1.586 1.563 1.586 1.202 0 3.325-.733 5.088-1.668V17.785h4.888v19.808h-3.726l-.481-1.667c-2.444 1.22-5.529 2.074-7.812 2.074-3.246 0-4.407-2.318-4.407-5.857V17.785zM168 37.593h-4.888V9.691L168 9v28.593z"/></g></svg>`;
|
||||
return require('./templates/body.html.js')(vars);
|
||||
case 'root-class':
|
||||
return 'ember-loading';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
module.exports = ({ appName, environment, rootURL, config }) => `
|
||||
<noscript>
|
||||
<div style="margin: 0 auto;">
|
||||
<h2>JavaScript Required</h2>
|
||||
<p>Please enable JavaScript in your web browser to use Consul UI.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
<svg width="168" height="53" xmlns="http://www.w3.org/2000/svg"><g fill="#919FA8" fill-rule="evenodd"><path d="M26.078 32.12a5.586 5.586 0 1 1 5.577-5.599 5.577 5.577 0 0 1-5.577 5.6M37.009 29.328a2.56 2.56 0 1 1 2.56-2.56 2.551 2.551 0 0 1-2.56 2.56M46.916 31.669a2.56 2.56 0 1 1 .051-.21c-.028.066-.028.13-.051.21M44.588 25.068a2.565 2.565 0 0 1-2.672-.992 2.558 2.558 0 0 1-.102-2.845 2.564 2.564 0 0 1 4.676.764c.072.328.081.667.027 1a2.463 2.463 0 0 1-1.925 2.073M53.932 31.402a2.547 2.547 0 0 1-2.95 2.076 2.559 2.559 0 0 1-2.064-2.965 2.547 2.547 0 0 1 2.948-2.077 2.57 2.57 0 0 1 2.128 2.716.664.664 0 0 0-.05.228M51.857 25.103a2.56 2.56 0 1 1 2.108-2.945c.034.218.043.439.027.658a2.547 2.547 0 0 1-2.135 2.287M49.954 40.113a2.56 2.56 0 1 1 .314-1.037c-.02.366-.128.721-.314 1.037M48.974 16.893a2.56 2.56 0 1 1 .97-3.487c.264.446.375.965.317 1.479a2.56 2.56 0 0 1-1.287 2.008"/><path d="M26.526 52.603c-14.393 0-26.06-11.567-26.06-25.836C.466 12.498 12.133.931 26.526.931a25.936 25.936 0 0 1 15.836 5.307l-3.167 4.117A20.962 20.962 0 0 0 17.304 8.23C10.194 11.713 5.7 18.9 5.714 26.763c-.014 7.862 4.48 15.05 11.59 18.534a20.962 20.962 0 0 0 21.89-2.127l3.168 4.123a25.981 25.981 0 0 1-15.836 5.31z"/>${
|
||||
config.CONSUL_BINARY_TYPE !== 'oss' && config.CONSUL_BINARY_TYPE !== ''
|
||||
? `<path data-enterprise-logo d="M61 42.083h3.975v.785H61.87v2.136h2.882v.784H61.87v2.31h3.114v.785H61v-6.8zm6.907 1.018V48.9h-.828v-6.817h1.2l2.94 5.84v-5.84h.829V48.9h-1.193L67.907 43.1zm7.826-.225h-2.012v-.784h4.911v.784h-2.02V48.9h-.879v-6.024zm4.564-.793h3.975v.785h-3.106v2.136h2.882v.784h-2.882v2.31h3.114v.785h-3.992l.009-6.8zm8.605 4.347h-1.657v2.503h-.87v-6.85h2.576c1.45 0 1.963.635 1.963 1.67v.984a1.435 1.435 0 0 1-1.077 1.585l1.756 2.57h-1.002l-1.69-2.462zm0-3.562h-1.657v2.778h1.657c.828 0 1.118-.234 1.118-.901v-.968c.024-.676-.265-.901-1.094-.901l-.024-.008zm4.488-.785h2.485c1.45 0 1.963.635 1.963 1.67v1.009c0 1.05-.505 1.668-1.963 1.668H94.3v2.47h-.87l-.04-6.817zm2.419.785h-1.54v2.803h1.54c.828 0 1.118-.234 1.118-.901v-1.001c0-.668-.282-.893-1.118-.893v-.008zm6.368 3.562h-1.656v2.503h-.87v-6.85h2.576c1.45 0 1.963.635 1.963 1.67v.984a1.435 1.435 0 0 1-1.077 1.585l1.756 2.57h-1.002l-1.69-2.462zm0-3.562h-1.656v2.778h1.656c.829 0 1.118-.234 1.118-.901v-.968c.017-.676-.265-.901-1.101-.901l-.017-.008zm5.392 6.032h-.828v-6.817h.828V48.9zm4.14.1a5.76 5.76 0 0 1-2.012-.359l.141-.717c.605.195 1.236.3 1.872.308 1.085 0 1.308-.283 1.308-1.06 0-.917 0-1-1.4-1.317-1.656-.368-1.83-.685-1.83-2.095 0-1.184.49-1.76 2.162-1.76a7.648 7.648 0 0 1 1.83.225l-.074.743a8.223 8.223 0 0 0-1.74-.192c-1.11 0-1.308.225-1.308 1.01 0 .942 0 .984 1.342 1.318 1.797.45 1.888.717 1.888 2.044.033 1.176-.315 1.852-2.178 1.852zm4.332-6.917h3.95v.785h-3.105v2.136h2.882v.784h-2.882v2.31H120v.785h-3.992l.033-6.8z" fill-rule="nonzero"/>`
|
||||
: ``
|
||||
}<path d="M61 30.15V17.948c0-4.962 2.845-7.85 9.495-7.85 2.484 0 5.048.326 7.252.895l-.561 4.433c-2.164-.406-4.688-.691-6.53-.691-3.486 0-4.608 1.22-4.608 4.108v10.412c0 2.888 1.122 4.108 4.607 4.108 1.843 0 4.367-.284 6.53-.691l.562 4.433c-2.204.57-4.768.895-7.252.895C63.845 38 61 35.112 61 30.15zm36.808.04c0 4.068-1.802 7.81-8.493 7.81-6.69 0-8.494-3.742-8.494-7.81v-5.002c0-4.067 1.803-7.81 8.494-7.81 6.69 0 8.493 3.743 8.493 7.81v5.003zm-4.887-5.165c0-2.237-1.002-3.416-3.606-3.416s-3.606 1.18-3.606 3.416v5.328c0 2.237 1.002 3.417 3.606 3.417s3.606-1.18 3.606-3.417v-5.328zm25.79 12.568h-4.887V23.764c0-1.057-.44-1.586-1.563-1.586-1.201 0-3.325.732-5.088 1.668v13.747h-4.887V17.785h3.726l.48 1.668c2.444-1.22 5.53-2.074 7.813-2.074 3.245 0 4.407 2.318 4.407 5.857v14.357zm18.26-5.775c0 3.823-1.162 6.182-7.052 6.182-2.083 0-4.927-.488-6.73-1.139l.68-3.782c1.643.488 3.807.854 5.81.854 2.164 0 2.484-.488 2.484-1.993 0-1.22-.24-1.83-3.405-2.603-4.768-1.18-5.329-2.4-5.329-6.223 0-3.986 1.723-5.735 7.292-5.735 1.803 0 4.166.244 5.85.691l-.482 3.945c-1.482-.284-3.846-.569-5.368-.569-2.124 0-2.484.488-2.484 1.708 0 1.587.12 1.709 2.764 2.4 5.449 1.464 5.97 2.196 5.97 6.264zm4.357-14.033h4.887v13.83c0 1.057.441 1.586 1.563 1.586 1.202 0 3.325-.733 5.088-1.668V17.785h4.888v19.808h-3.726l-.481-1.667c-2.444 1.22-5.529 2.074-7.812 2.074-3.246 0-4.407-2.318-4.407-5.857V17.785zM168 37.593h-4.888V9.691L168 9v28.593z"/></g></svg>
|
||||
<script src="${rootURL}assets/vendor.js"></script>
|
||||
${environment === 'test' ? `<script src="${rootURL}assets/test-support.js"></script>` : ``}
|
||||
<script>
|
||||
var appendScript = function(src) {
|
||||
var $script = document.createElement('script');
|
||||
$script.src = src;
|
||||
document.body.appendChild($script);
|
||||
}
|
||||
if(!('TextDecoder' in window)) {
|
||||
appendScript('${rootURL}assets/encoding-indexes.js');
|
||||
appendScript('${rootURL}assets/encoding.js');
|
||||
}
|
||||
</script>
|
||||
<script src="${rootURL}assets/${appName}.js"></script>
|
||||
<script>
|
||||
CodeMirror.modeURL = {
|
||||
replace: function(n, mode) {
|
||||
switch(mode) {
|
||||
case 'javascript':
|
||||
return '${rootURL}assets/codemirror/mode/javascript/javascript.js';
|
||||
case 'ruby':
|
||||
return '${rootURL}assets/codemirror/mode/ruby/ruby.js';
|
||||
case 'yaml':
|
||||
return '${rootURL}assets/codemirror/mode/yaml/yaml.js';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
${environment === 'test' ? `<script src="${rootURL}assets/tests.js"></script>` : ``}
|
||||
`;
|
|
@ -0,0 +1,37 @@
|
|||
module.exports = ({ appName, environment, rootURL, config }) => `
|
||||
<!-- CONSUL_VERSION: ${config.CONSUL_VERSION} -->
|
||||
<script>
|
||||
var setConfig = function(appName, config) {
|
||||
var $meta = document.querySelector('meta[name="' + appName + '/config/environment"]');
|
||||
var defaultConfig = JSON.parse(decodeURIComponent($meta.getAttribute('content')));
|
||||
(
|
||||
function set(blob, config) {
|
||||
Object.keys(config).forEach(
|
||||
function(key) {
|
||||
var value = config[key];
|
||||
if(Object.prototype.toString.call(value) === '[object Object]') {
|
||||
set(blob[key], config[key]);
|
||||
} else {
|
||||
blob[key] = config[key];
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
)(defaultConfig, config);
|
||||
$meta.setAttribute('content', encodeURIComponent(JSON.stringify(defaultConfig)));
|
||||
}
|
||||
setConfig(
|
||||
'${appName}',
|
||||
{
|
||||
rootURL: '${rootURL}'
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<link rel="icon" type="image/png" href="${rootURL}assets/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="${rootURL}assets/favicon-16x16.png" sizes="16x16">
|
||||
<link integrity="" rel="stylesheet" href="${rootURL}assets/vendor.css">
|
||||
<link integrity="" rel="stylesheet" href="${rootURL}assets/${appName}.css">
|
||||
${
|
||||
environment === 'test' ? `<link rel="stylesheet" href="${rootURL}assets/test-support.css">` : ``
|
||||
}
|
||||
`;
|
|
@ -6,14 +6,9 @@
|
|||
<title>ConsulUi Tests</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{{content-for "head"}}
|
||||
{{content-for "test-head"}}
|
||||
|
||||
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||
<link rel="stylesheet" href="{{rootURL}}assets/consul-ui.css">
|
||||
<link rel="stylesheet" href="{{rootURL}}assets/test-support.css">
|
||||
|
||||
{{content-for "head-footer"}}
|
||||
{{content-for "test-head-footer"}}
|
||||
</head>
|
||||
|
@ -22,10 +17,6 @@
|
|||
{{content-for "test-body"}}
|
||||
|
||||
<script src="/testem.js" integrity=""></script>
|
||||
<script src="{{rootURL}}assets/vendor.js"></script>
|
||||
<script src="{{rootURL}}assets/test-support.js"></script>
|
||||
<script src="{{rootURL}}assets/consul-ui.js"></script>
|
||||
<script src="{{rootURL}}assets/tests.js"></script>
|
||||
|
||||
{{content-for "body-footer"}}
|
||||
{{content-for "test-body-footer"}}
|
||||
|
|
|
@ -183,6 +183,12 @@ The table below shows this endpoint's support for
|
|||
case of a Script, HTTP, TCP, or gRPC check. Can be specified in the form of "10s"
|
||||
or "5m" (i.e., 10 seconds or 5 minutes, respectively).
|
||||
|
||||
- `OutputMaxSize` `(positive int: 4096)` - Allow to put a maximum size of text
|
||||
for the given check. This value must be greater than 0, by default, the value
|
||||
is 4k.
|
||||
The value can be further limited for all checks of a given agent using the
|
||||
`check_output_max_size` flag in the agent.
|
||||
|
||||
- `TLSSkipVerify` `(bool: false)` - Specifies if the certificate for an HTTPS
|
||||
check should not be verified.
|
||||
|
||||
|
|
|
@ -132,6 +132,14 @@ will exit with an error at startup.
|
|||
[go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
|
||||
template
|
||||
|
||||
* <a name="check_output_max_size"></a><a href="#check_output_max_size">`-check_output_max_size`</a> -
|
||||
Override the default limit of 4k for maximum size of checks, this is a positive
|
||||
value.
|
||||
By limiting this size, it allows to put less pressure on Consul servers when
|
||||
many checks are having a very large output in their checks.
|
||||
In order to completely disable check output capture, it is possible to
|
||||
use <a href="#discard_check_output">`discard_check_output`</a>.
|
||||
|
||||
* <a name="_client"></a><a href="#_client">`-client`</a> - The address to which
|
||||
Consul will bind client interfaces, including the HTTP and DNS servers. By
|
||||
default, this is "127.0.0.1", allowing only loopback connections. In Consul
|
||||
|
@ -457,6 +465,8 @@ will exit with an error at startup.
|
|||
the Web UI resources for Consul. This will automatically enable the Web UI. The directory must be
|
||||
readable to the agent. Starting with Consul version 0.7.0 and later, the Web UI assets are included in the binary so this flag is no longer necessary; specifying only the `-ui` flag is enough to enable the Web UI. Specifying both the '-ui' and '-ui-dir' flags will result in an error.
|
||||
|
||||
* <a name="_ui_content_path"></a><a href="#_ui_content_path">`-ui-content-path`</a> - This flag provides the option to change the path the Consul UI loads from and will be displayed in the browser. By default, the path is `/ui/`, for example `http://localhost:8500/ui/`. Only alphanumerics, `-`, and `_` are allowed in a custom path. `/v1/` is not allowed as it would overwrite the API endpoint.
|
||||
|
||||
## <a name="configuration_files"></a>Configuration Files
|
||||
|
||||
In addition to the command-line options, configuration can be put into
|
||||
|
|
|
@ -216,15 +216,15 @@ definition](/docs/connect/registration/service-registration.html) or
|
|||
|
||||
## Advanced Configuration
|
||||
|
||||
To support more flexibility when configuring Envoy, several "lower-level" options exist that
|
||||
exist that require knowledge of Envoy's configuration format.
|
||||
Many allow configuring a subsection of either the bootstrap or
|
||||
To support more flexibility when configuring Envoy, several "lower-level" options exist
|
||||
that require knowledge of Envoy's configuration format.
|
||||
Many options allow configuring a subsection of either the bootstrap or
|
||||
dynamic configuration using your own custom protobuf config.
|
||||
|
||||
We separate these into two sets, [Advanced Bootstrap
|
||||
Options](#advanced-bootstrap-options) and [Escape Hatch
|
||||
Overrides](#escape-hatch-overrides). Both require writing Envoy config in it's
|
||||
protobuf JSON encoding. Advanced options are smaller chunks that might
|
||||
Overrides](#escape-hatch-overrides). Both require writing Envoy config in the
|
||||
protobuf JSON encoding. Advanced options cover smaller chunks that might
|
||||
commonly need to be set for tasks like configuring tracing. In contrast, escape hatches
|
||||
give almost complete control over the proxy setup, but require operators to
|
||||
manually code the entire configuration in protobuf JSON.
|
||||
|
|
Loading…
Reference in New Issue