2021-05-02 20:33:13 +00:00
|
|
|
package diagnose
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2021-05-02 23:21:06 +00:00
|
|
|
"strings"
|
2021-05-02 20:33:13 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/sdk/physical"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
success string = "success"
|
|
|
|
secretVal string = "diagnoseSecret"
|
|
|
|
|
2021-05-25 22:23:20 +00:00
|
|
|
LatencyWarning string = "latency above 100 ms: "
|
|
|
|
DirAccessErr string = "consul storage does not connect to local agent, but directly to server"
|
|
|
|
AddrDNExistErr string = "config address does not exist: 127.0.0.1:8500 will be used"
|
|
|
|
wrongRWValsPrefix string = "Storage get and put gave wrong values: "
|
|
|
|
latencyThreshold time.Duration = time.Millisecond * 100
|
2021-05-02 20:33:13 +00:00
|
|
|
)
|
|
|
|
|
2021-05-25 22:23:20 +00:00
|
|
|
func EndToEndLatencyCheckWrite(ctx context.Context, uuid string, b physical.Backend) (time.Duration, error) {
|
|
|
|
start := time.Now()
|
|
|
|
err := b.Put(context.Background(), &physical.Entry{Key: uuid, Value: []byte(secretVal)})
|
|
|
|
duration := time.Since(start)
|
|
|
|
if err != nil {
|
|
|
|
return time.Duration(0), err
|
|
|
|
}
|
|
|
|
if duration > latencyThreshold {
|
|
|
|
return duration, nil
|
2021-05-02 20:33:13 +00:00
|
|
|
}
|
2021-05-25 22:23:20 +00:00
|
|
|
return time.Duration(0), nil
|
|
|
|
}
|
2021-05-02 20:33:13 +00:00
|
|
|
|
2021-05-25 22:23:20 +00:00
|
|
|
func EndToEndLatencyCheckRead(ctx context.Context, uuid string, b physical.Backend) (time.Duration, error) {
|
|
|
|
|
|
|
|
start := time.Now()
|
|
|
|
val, err := b.Get(context.Background(), uuid)
|
|
|
|
duration := time.Since(start)
|
|
|
|
if err != nil {
|
|
|
|
return time.Duration(0), err
|
|
|
|
}
|
|
|
|
if val == nil {
|
|
|
|
return time.Duration(0), fmt.Errorf("no value found when reading generated data")
|
2021-05-02 20:33:13 +00:00
|
|
|
}
|
2021-05-25 22:23:20 +00:00
|
|
|
if val.Key != uuid && string(val.Value) != secretVal {
|
|
|
|
return time.Duration(0), fmt.Errorf(wrongRWValsPrefix+"expecting diagnose, but got %s, %s", val.Key, val.Value)
|
|
|
|
}
|
|
|
|
if duration > latencyThreshold {
|
|
|
|
return duration, nil
|
|
|
|
}
|
|
|
|
return time.Duration(0), nil
|
|
|
|
}
|
|
|
|
func EndToEndLatencyCheckDelete(ctx context.Context, uuid string, b physical.Backend) (time.Duration, error) {
|
2021-05-02 20:33:13 +00:00
|
|
|
|
2021-05-25 22:23:20 +00:00
|
|
|
start := time.Now()
|
|
|
|
err := b.Delete(context.Background(), uuid)
|
|
|
|
duration := time.Since(start)
|
|
|
|
if err != nil {
|
|
|
|
return time.Duration(0), err
|
|
|
|
}
|
|
|
|
if duration > latencyThreshold {
|
|
|
|
return duration, nil
|
2021-05-02 20:33:13 +00:00
|
|
|
}
|
2021-05-25 22:23:20 +00:00
|
|
|
return time.Duration(0), nil
|
2021-05-02 20:33:13 +00:00
|
|
|
}
|
2021-05-02 23:21:06 +00:00
|
|
|
|
|
|
|
// ConsulDirectAccess verifies that consul is connecting to local agent,
|
|
|
|
// versus directly to a remote server. We can only assume that the local address
|
|
|
|
// is a server, not a client.
|
|
|
|
func ConsulDirectAccess(config map[string]string) string {
|
|
|
|
configAddr, ok := config["address"]
|
|
|
|
if !ok {
|
|
|
|
return AddrDNExistErr
|
|
|
|
}
|
|
|
|
if !strings.Contains(configAddr, "localhost") && !strings.Contains(configAddr, "127.0.0.1") {
|
|
|
|
return DirAccessErr
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|