mirror of https://github.com/hashicorp/boundary
feat: Decode Summary File (#3408)
* feat: Decode Summary File - Add support for decoding BSR session, connection and channel summary file - Introduce base summary interfaces that other protocols can extend - Add new SSH register allocation function for getting SSH Channel Summary Typepull/3427/head
parent
88adfecb59
commit
fd3091d8dc
@ -0,0 +1,51 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package bsr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SummaryAllocFunc is a function that returns a summary type
|
||||
type SummaryAllocFunc func(ctx context.Context) Summary
|
||||
|
||||
// summaryAllocFuncRegistry mappings of protocols and container type
|
||||
// for each SummaryAllocFunc
|
||||
type summaryAllocFuncRegistry map[Protocol]map[ContainerType]SummaryAllocFunc
|
||||
|
||||
func (r summaryAllocFuncRegistry) get(p Protocol, c ContainerType) (SummaryAllocFunc, bool) {
|
||||
protocol, ok := r[p]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
af, ok := protocol[c]
|
||||
return af, ok
|
||||
}
|
||||
|
||||
var summaryAllocFuncs summaryAllocFuncRegistry
|
||||
|
||||
// RegisterSummaryAllocFunc registers a SummaryAllocFunc for the given Protocol.
|
||||
// A given Protocol and Container can only have one SummaryAllocFunc function
|
||||
// registered.
|
||||
func RegisterSummaryAllocFunc(p Protocol, c ContainerType, af SummaryAllocFunc) error {
|
||||
const op = "bsr.RegisterSummaryAllocFunc"
|
||||
|
||||
if summaryAllocFuncs == nil {
|
||||
summaryAllocFuncs = make(map[Protocol]map[ContainerType]SummaryAllocFunc)
|
||||
}
|
||||
|
||||
protocol, ok := summaryAllocFuncs[p]
|
||||
if !ok {
|
||||
protocol = make(map[ContainerType]SummaryAllocFunc)
|
||||
}
|
||||
|
||||
_, ok = protocol[c]
|
||||
if ok {
|
||||
return fmt.Errorf("%s: %s protocol with %s container: %w", op, p, c, ErrAlreadyRegistered)
|
||||
}
|
||||
protocol[c] = af
|
||||
summaryAllocFuncs[p] = protocol
|
||||
return nil
|
||||
}
|
||||
@ -0,0 +1,190 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package bsr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRegisterSummaryAllocFunc_TestProtocol(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
startTime := time.Now()
|
||||
endTime := time.Now()
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
p Protocol
|
||||
c ContainerType
|
||||
cf SummaryAllocFunc
|
||||
wantP Protocol
|
||||
want *BaseSummary
|
||||
wantRegisterErr error
|
||||
wantGetAllocErr bool
|
||||
}{
|
||||
{
|
||||
"valid summary",
|
||||
Protocol("TEST_PROTOCOL"),
|
||||
ChannelContainer,
|
||||
func(ctx context.Context) Summary {
|
||||
return &BaseSummary{
|
||||
Id: "TEST_ID",
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
}
|
||||
},
|
||||
Protocol("TEST_PROTOCOL"),
|
||||
&BaseSummary{
|
||||
Id: "TEST_ID",
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
},
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"already-registered-container",
|
||||
Protocol("TEST_PROTOCOL"),
|
||||
ChannelContainer,
|
||||
nil,
|
||||
Protocol("TEST_PROTOCOL"),
|
||||
&BaseSummary{},
|
||||
errors.New("bsr.RegisterSummaryAllocFunc: TEST_PROTOCOL protocol with channel container: type already registered"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid-protocol",
|
||||
Protocol("TEST_PROTOCOL_2"),
|
||||
ChannelContainer,
|
||||
nil,
|
||||
Protocol("TEST_INVALID_PROTOCOL"),
|
||||
&BaseSummary{},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := RegisterSummaryAllocFunc(tc.p, tc.c, tc.cf)
|
||||
if tc.wantRegisterErr != nil {
|
||||
assert.EqualError(t, tc.wantRegisterErr, err.Error())
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
af, ok := summaryAllocFuncs.get(tc.wantP, tc.c)
|
||||
if tc.wantGetAllocErr {
|
||||
require.False(t, ok, "found invalid summary")
|
||||
return
|
||||
}
|
||||
require.True(t, ok, "could not get summary")
|
||||
|
||||
got := af(ctx)
|
||||
|
||||
assert.Equal(t, tc.want.GetId(), got.GetId())
|
||||
assert.Equal(t, tc.want.GetStartTime(), got.GetStartTime())
|
||||
assert.Equal(t, tc.want.GetEndTime(), got.GetEndTime())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterSummaryAllocFunc_TestChannel(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
protocol := Protocol("TEST_CHANNEL_PROTOCOL")
|
||||
chs := &BaseChannelSummary{
|
||||
Id: "TEST_ID",
|
||||
ConnectionRecordingId: "TEST_CONNECTION_RECORDING_ID",
|
||||
ChannelType: "CONTAINER",
|
||||
StartTime: time.Now(),
|
||||
EndTime: time.Now(),
|
||||
BytesUp: 100,
|
||||
BytesDown: 200,
|
||||
}
|
||||
|
||||
err := RegisterSummaryAllocFunc(protocol, ChannelContainer, func(ctx context.Context) Summary {
|
||||
return chs
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
af, ok := summaryAllocFuncs.get(protocol, ChannelContainer)
|
||||
require.True(t, ok, "could not get channel summary")
|
||||
|
||||
cf := af(ctx)
|
||||
got := cf.(*BaseChannelSummary)
|
||||
|
||||
assert.Equal(t, chs.GetId(), got.GetId())
|
||||
assert.Equal(t, chs.GetConnectionRecordingId(), got.GetConnectionRecordingId())
|
||||
assert.Equal(t, chs.GetChannelType(), got.GetChannelType())
|
||||
assert.Equal(t, chs.GetStartTime(), got.GetStartTime())
|
||||
assert.Equal(t, chs.GetEndTime(), got.GetEndTime())
|
||||
assert.Equal(t, chs.GetBytesUp(), got.GetBytesUp())
|
||||
assert.Equal(t, chs.GetBytesDown(), got.GetBytesDown())
|
||||
}
|
||||
|
||||
func TestRegisterSummaryAllocFunc_TestConnection(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
protocol := Protocol("TEST_CONNECTION_PROTOCOL")
|
||||
chs := &BaseConnectionSummary{
|
||||
Id: "TEST_ID",
|
||||
ChannelCount: 1,
|
||||
StartTime: time.Now(),
|
||||
EndTime: time.Now(),
|
||||
BytesUp: 100,
|
||||
BytesDown: 200,
|
||||
}
|
||||
|
||||
err := RegisterSummaryAllocFunc(protocol, ConnectionContainer, func(ctx context.Context) Summary {
|
||||
return chs
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
af, ok := summaryAllocFuncs.get(protocol, ConnectionContainer)
|
||||
require.True(t, ok, "could not get connection summary")
|
||||
|
||||
cf := af(ctx)
|
||||
got := cf.(*BaseConnectionSummary)
|
||||
|
||||
assert.Equal(t, chs.GetId(), got.GetId())
|
||||
assert.Equal(t, chs.GetChannelCount(), got.GetChannelCount())
|
||||
assert.Equal(t, chs.GetStartTime(), got.GetStartTime())
|
||||
assert.Equal(t, chs.GetEndTime(), got.GetEndTime())
|
||||
assert.Equal(t, chs.GetBytesUp(), got.GetBytesUp())
|
||||
assert.Equal(t, chs.GetBytesDown(), got.GetBytesDown())
|
||||
}
|
||||
|
||||
func TestRegisterSummaryAllocFunc_TestSession(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
protocol := Protocol("TEST_SESSION_PROTOCOL")
|
||||
chs := &BaseSessionSummary{
|
||||
Id: "TEST_ID",
|
||||
ConnectionCount: 1,
|
||||
StartTime: time.Now(),
|
||||
EndTime: time.Now(),
|
||||
}
|
||||
|
||||
err := RegisterSummaryAllocFunc(protocol, SessionContainer, func(ctx context.Context) Summary {
|
||||
return chs
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
af, ok := summaryAllocFuncs.get(protocol, SessionContainer)
|
||||
require.True(t, ok, "could not get session summary")
|
||||
|
||||
cf := af(ctx)
|
||||
got := cf.(*BaseSessionSummary)
|
||||
|
||||
assert.Equal(t, chs.GetId(), got.GetId())
|
||||
assert.Equal(t, chs.GetConnectionCount(), got.GetConnectionCount())
|
||||
assert.Equal(t, chs.GetStartTime(), got.GetStartTime())
|
||||
assert.Equal(t, chs.GetEndTime(), got.GetEndTime())
|
||||
}
|
||||
Loading…
Reference in new issue