summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md18
-rw-r--r--internal/clients/args.go28
-rw-r--r--internal/datas/rbuffer.go49
-rw-r--r--internal/datas/rbuffer_test.go106
-rw-r--r--internal/options/options.go4
-rw-r--r--internal/ssh/client/authmethods.go10
6 files changed, 193 insertions, 22 deletions
diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index 4bfad52..0000000
--- a/TODO.md
+++ /dev/null
@@ -1,18 +0,0 @@
-TODO
-====
-
-This is a loose list of what to do. Maybe for the next releae or maybe for a later one.
-
-[ ] Client 4.x should print an error and exit when trying to connect to a 3.x server.
-[ ] Client 3.x should print an error and exit when trying to connect to a 4.x server.
-[ ] Create a GitHub Wiki
- [ ] Migrate existing documentation + update animated Gifs
- [ ] Document that can use additional args as file lists
- [ ] Document spartan mode
- [ ] Document serverless mode
- [ ] Document color configuratio
- [ ] Go through the git history and document more stuff
-[ ] Manual test/adjust dtail colors
-[ ] Integration test for dtail in serverless mode
-[ ] Document how to run ingeration tests
-[ ] dserver scheduled queries integration test
diff --git a/internal/clients/args.go b/internal/clients/args.go
new file mode 100644
index 0000000..684dadd
--- /dev/null
+++ b/internal/clients/args.go
@@ -0,0 +1,28 @@
+package clients
+
+import (
+ "github.com/mimecast/dtail/internal/lcontext"
+ "github.com/mimecast/dtail/internal/omode"
+
+ gossh "golang.org/x/crypto/ssh"
+)
+
+// Args is a helper struct to summarize common client arguments.
+type Args struct {
+ lcontext.LContext
+ RegexStr string
+ Mode omode.Mode
+ ServersStr string
+ UserName string
+ What string
+ Arguments []string
+ RegexInvert bool
+ TrustAllHosts bool
+ Discovery string
+ ConnectionsPerCPU int
+ Timeout int
+ SSHAuthMethods []gossh.AuthMethod
+ SSHHostKeyCallback gossh.HostKeyCallback
+ PrivateKeyPathFile string
+ Quiet bool
+}
diff --git a/internal/datas/rbuffer.go b/internal/datas/rbuffer.go
new file mode 100644
index 0000000..df8f622
--- /dev/null
+++ b/internal/datas/rbuffer.go
@@ -0,0 +1,49 @@
+package datas
+
+import "fmt"
+
+// RBuffer is a simple circular string ring buffer data structure.
+type RBuffer struct {
+ Capacity int
+ size int
+ readPos int
+ writePos int
+ data []string
+}
+
+// NewRBuffer creates a new string ring buffer.
+func NewRBuffer(capacity int) (*RBuffer, error) {
+ if capacity < 1 {
+ return nil, fmt.Errorf("RBuffer capacity must not be less than 1")
+ }
+
+ r := RBuffer{
+ Capacity: capacity,
+ size: capacity + 1,
+ data: make([]string, capacity+1),
+ }
+
+ return &r, nil
+}
+
+// Add a value.
+func (r *RBuffer) Add(value string) {
+ r.data[r.writePos] = value
+ r.writePos = (r.writePos + 1) % r.size
+
+ if r.writePos == r.readPos {
+ r.readPos = (r.readPos + 1) % r.size
+ }
+}
+
+// Get a value.
+func (r *RBuffer) Get() (string, bool) {
+ if r.readPos == r.writePos {
+ // RBuffer is empty.
+ return "", false
+ }
+
+ value := r.data[r.readPos]
+ r.readPos = (r.readPos + 1) % r.size
+ return value, true
+}
diff --git a/internal/datas/rbuffer_test.go b/internal/datas/rbuffer_test.go
new file mode 100644
index 0000000..843bb8e
--- /dev/null
+++ b/internal/datas/rbuffer_test.go
@@ -0,0 +1,106 @@
+package datas
+
+import (
+ "fmt"
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestRBufferOneElement(t *testing.T) {
+ r, err := NewRBuffer(1)
+ if err != nil {
+ t.Errorf("Expected error creating ring buffer with capacity 1")
+ }
+
+ testRBufferValues(t, r, []string{"Hello world"})
+ testRBufferValues(t, r, []string{"Hello world", "Hello universe"})
+}
+
+func TestRBuffer(t *testing.T) {
+ if _, err := NewRBuffer(0); err == nil {
+ t.Errorf("Expected error creating ring buffer with capacity 0")
+ }
+
+ r, err := NewRBuffer(10)
+ if err != nil {
+ t.Errorf("Error creating ring buffer with capacity 10: %v", err)
+ }
+
+ fiveValues := []string{
+ "42 is the answer!",
+ "Scorpion: Get over here!",
+ "Have you swiped your nectar card?",
+ "Please mind the gap between the train and the platform!",
+ "Visit DTail at https://dtail.dev",
+ }
+ testRBufferValues(t, r, fiveValues)
+
+ moreFiveValues := []string{
+ "I love Golang",
+ "As a contrast, I also love Perl",
+ "Mimecast: Stop Bad Things From Happening to Good Organizations",
+ "We are the Buetow Brothers",
+ "London is calling",
+ }
+ tenValues := append(fiveValues, moreFiveValues...)
+ testRBufferValues(t, r, tenValues)
+}
+
+func TestRandomRBuffer(t *testing.T) {
+ for i := 0; i < 100; i++ {
+ testRandomRBuffer(t)
+ }
+}
+
+func testRandomRBuffer(t *testing.T) {
+ rand.Seed(time.Now().UnixNano())
+
+ maxCapacity := 1000
+ minCapacity := 1
+ capacity := rand.Intn(maxCapacity-minCapacity) + minCapacity
+ r, err := NewRBuffer(capacity)
+ if err != nil {
+ t.Errorf("Error creating ring buffer with capacity %d: %v", capacity, err)
+ }
+
+ numValues := rand.Intn(capacity * 2)
+ values := make([]string, numValues)
+ for i := 0; i < numValues; i++ {
+ values = append(values, fmt.Sprintf("%d.%d", i, rand.Int()))
+ }
+
+ testRBufferValues(t, r, values)
+}
+
+func testRBufferValues(t *testing.T, r *RBuffer, values []string) {
+ value, ok := r.Get()
+ if ok {
+ t.Errorf("Expected not ok reading from empty ring buffer but got ok and value '%s'", value)
+ }
+
+ for _, value := range values {
+ r.Add(value)
+ }
+
+ expectedValues := values
+ overCapacity := len(values) - r.Capacity
+ if overCapacity > 0 {
+ expectedValues = values[overCapacity:]
+ }
+
+ for _, expected := range expectedValues {
+ value, ok := r.Get()
+ if !ok {
+ t.Errorf("Expected value '%s' but got nothing", expected)
+ }
+ if value != expected {
+ t.Errorf("Expected value '%s' but got value '%v'", expected, value)
+ }
+ }
+
+ value, ok = r.Get()
+ if ok {
+ t.Errorf("Expected not ok reading from empty ring buffer but got ok and value '%s'", value)
+ }
+}
diff --git a/internal/options/options.go b/internal/options/options.go
new file mode 100644
index 0000000..9eb4501
--- /dev/null
+++ b/internal/options/options.go
@@ -0,0 +1,4 @@
+package options
+
+// Options is a map of all options specified by a DTail client to be transferred to the DTail server (e.g. such as grep context control such as -after, -before and -max).
+type Options map[string]string
diff --git a/internal/ssh/client/authmethods.go b/internal/ssh/client/authmethods.go
index b1e514d..37f8382 100644
--- a/internal/ssh/client/authmethods.go
+++ b/internal/ssh/client/authmethods.go
@@ -36,10 +36,12 @@ func initKnownHostsAuthMethods(trustAllHosts bool, throttleCh chan struct{},
dlog.Client.FatalPanic(knownHostsPath, err)
}
dlog.Client.Debug("initKnownHostsAuthMethods", "Added known hosts file path", knownHostsPath)
- if config.Client.ExperimentalFeaturesEnable {
- sshAuthMethods = append(sshAuthMethods, gossh.Password("experimental feature test"))
- dlog.Client.Debug("initKnownHostsAuthMethods", "Added experimental method to list of auth methods")
- }
+ /*
+ if config.Client.ExperimentalFeaturesEnable {
+ sshAuthMethods = append(sshAuthMethods, gossh.Password("experimental feature test"))
+ dlog.Client.Debug("initKnownHostsAuthMethods", "Added experimental method to list of auth methods")
+ }
+ */
// First try to read custom private key path.
if privateKeyPath != "" {