mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Audit: some refactoring out of types.go (#25511)
* some refactoring out of types.go * tests for metrics tag, parallelize other tests
This commit is contained in:
@@ -17,6 +17,13 @@ import (
|
|||||||
|
|
||||||
var _ eventlogger.Node = (*EntryFilter)(nil)
|
var _ eventlogger.Node = (*EntryFilter)(nil)
|
||||||
|
|
||||||
|
// EntryFilter should be used to filter audit requests and responses which should
|
||||||
|
// make it to a sink.
|
||||||
|
type EntryFilter struct {
|
||||||
|
// the evaluator for the bexpr expression that should be applied by the node.
|
||||||
|
evaluator *bexpr.Evaluator
|
||||||
|
}
|
||||||
|
|
||||||
// NewEntryFilter should be used to create an EntryFilter node.
|
// NewEntryFilter should be used to create an EntryFilter node.
|
||||||
// The filter supplied should be in bexpr format and reference fields from logical.LogInputBexpr.
|
// The filter supplied should be in bexpr format and reference fields from logical.LogInputBexpr.
|
||||||
func NewEntryFilter(filter string) (*EntryFilter, error) {
|
func NewEntryFilter(filter string) (*EntryFilter, error) {
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ var (
|
|||||||
_ eventlogger.Node = (*EntryFormatter)(nil)
|
_ eventlogger.Node = (*EntryFormatter)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EntryFormatter should be used to format audit requests and responses.
|
||||||
|
type EntryFormatter struct {
|
||||||
|
salter Salter
|
||||||
|
headerFormatter HeaderFormatter
|
||||||
|
config FormatterConfig
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
// NewEntryFormatter should be used to create an EntryFormatter.
|
// NewEntryFormatter should be used to create an EntryFormatter.
|
||||||
// Accepted options: WithHeaderFormatter, WithPrefix.
|
// Accepted options: WithHeaderFormatter, WithPrefix.
|
||||||
func NewEntryFormatter(config FormatterConfig, salter Salter, opt ...Option) (*EntryFormatter, error) {
|
func NewEntryFormatter(config FormatterConfig, salter Salter, opt ...Option) (*EntryFormatter, error) {
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ const testFormatJSONReqBasicStrFmt = `
|
|||||||
|
|
||||||
// TestNewEntryFormatter ensures we can create new EntryFormatter structs.
|
// TestNewEntryFormatter ensures we can create new EntryFormatter structs.
|
||||||
func TestNewEntryFormatter(t *testing.T) {
|
func TestNewEntryFormatter(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
UseStaticSalt bool
|
UseStaticSalt bool
|
||||||
Options []Option // Only supports WithPrefix
|
Options []Option // Only supports WithPrefix
|
||||||
@@ -154,6 +156,8 @@ func TestNewEntryFormatter(t *testing.T) {
|
|||||||
|
|
||||||
// TestEntryFormatter_Reopen ensures that we do not get an error when calling Reopen.
|
// TestEntryFormatter_Reopen ensures that we do not get an error when calling Reopen.
|
||||||
func TestEntryFormatter_Reopen(t *testing.T) {
|
func TestEntryFormatter_Reopen(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ss := newStaticSalt(t)
|
ss := newStaticSalt(t)
|
||||||
cfg, err := NewFormatterConfig()
|
cfg, err := NewFormatterConfig()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -166,6 +170,8 @@ func TestEntryFormatter_Reopen(t *testing.T) {
|
|||||||
|
|
||||||
// TestEntryFormatter_Type ensures that the node is a 'formatter' type.
|
// TestEntryFormatter_Type ensures that the node is a 'formatter' type.
|
||||||
func TestEntryFormatter_Type(t *testing.T) {
|
func TestEntryFormatter_Type(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ss := newStaticSalt(t)
|
ss := newStaticSalt(t)
|
||||||
cfg, err := NewFormatterConfig()
|
cfg, err := NewFormatterConfig()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -179,6 +185,8 @@ func TestEntryFormatter_Type(t *testing.T) {
|
|||||||
// TestEntryFormatter_Process attempts to run the Process method to convert the
|
// TestEntryFormatter_Process attempts to run the Process method to convert the
|
||||||
// logical.LogInput within an audit event to JSON and JSONx (RequestEntry or ResponseEntry).
|
// logical.LogInput within an audit event to JSON and JSONx (RequestEntry or ResponseEntry).
|
||||||
func TestEntryFormatter_Process(t *testing.T) {
|
func TestEntryFormatter_Process(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
ExpectedErrorMessage string
|
ExpectedErrorMessage string
|
||||||
@@ -409,6 +417,8 @@ func BenchmarkAuditFileSink_Process(b *testing.B) {
|
|||||||
// TestEntryFormatter_FormatRequest exercises EntryFormatter.FormatRequest with
|
// TestEntryFormatter_FormatRequest exercises EntryFormatter.FormatRequest with
|
||||||
// varying inputs.
|
// varying inputs.
|
||||||
func TestEntryFormatter_FormatRequest(t *testing.T) {
|
func TestEntryFormatter_FormatRequest(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Input *logical.LogInput
|
Input *logical.LogInput
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -476,6 +486,8 @@ func TestEntryFormatter_FormatRequest(t *testing.T) {
|
|||||||
// TestEntryFormatter_FormatResponse exercises EntryFormatter.FormatResponse with
|
// TestEntryFormatter_FormatResponse exercises EntryFormatter.FormatResponse with
|
||||||
// varying inputs.
|
// varying inputs.
|
||||||
func TestEntryFormatter_FormatResponse(t *testing.T) {
|
func TestEntryFormatter_FormatResponse(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Input *logical.LogInput
|
Input *logical.LogInput
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -543,6 +555,8 @@ func TestEntryFormatter_FormatResponse(t *testing.T) {
|
|||||||
// TestEntryFormatter_Process_JSON ensures that the JSON output we get matches what
|
// TestEntryFormatter_Process_JSON ensures that the JSON output we get matches what
|
||||||
// we expect for the specified LogInput.
|
// we expect for the specified LogInput.
|
||||||
func TestEntryFormatter_Process_JSON(t *testing.T) {
|
func TestEntryFormatter_Process_JSON(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ss := newStaticSalt(t)
|
ss := newStaticSalt(t)
|
||||||
|
|
||||||
expectedResultStr := fmt.Sprintf(testFormatJSONReqBasicStrFmt, ss.salt.GetIdentifiedHMAC("foo"))
|
expectedResultStr := fmt.Sprintf(testFormatJSONReqBasicStrFmt, ss.salt.GetIdentifiedHMAC("foo"))
|
||||||
@@ -683,6 +697,8 @@ func TestEntryFormatter_Process_JSON(t *testing.T) {
|
|||||||
// TestEntryFormatter_Process_JSONx ensures that the JSONx output we get matches what
|
// TestEntryFormatter_Process_JSONx ensures that the JSONx output we get matches what
|
||||||
// we expect for the specified LogInput.
|
// we expect for the specified LogInput.
|
||||||
func TestEntryFormatter_Process_JSONx(t *testing.T) {
|
func TestEntryFormatter_Process_JSONx(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
s, err := salt.NewSalt(context.Background(), nil, nil)
|
s, err := salt.NewSalt(context.Background(), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
tempStaticSalt := &staticSalt{salt: s}
|
tempStaticSalt := &staticSalt{salt: s}
|
||||||
@@ -826,11 +842,7 @@ func TestEntryFormatter_Process_JSONx(t *testing.T) {
|
|||||||
// TestEntryFormatter_FormatResponse_ElideListResponses ensures that we correctly
|
// TestEntryFormatter_FormatResponse_ElideListResponses ensures that we correctly
|
||||||
// elide data in responses to LIST operations.
|
// elide data in responses to LIST operations.
|
||||||
func TestEntryFormatter_FormatResponse_ElideListResponses(t *testing.T) {
|
func TestEntryFormatter_FormatResponse_ElideListResponses(t *testing.T) {
|
||||||
type test struct {
|
t.Parallel()
|
||||||
name string
|
|
||||||
inputData map[string]any
|
|
||||||
expectedData map[string]any
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
inputData map[string]any
|
inputData map[string]any
|
||||||
@@ -957,6 +969,8 @@ func TestEntryFormatter_FormatResponse_ElideListResponses(t *testing.T) {
|
|||||||
// TestEntryFormatter_Process_NoMutation tests that the event returned by an
|
// TestEntryFormatter_Process_NoMutation tests that the event returned by an
|
||||||
// EntryFormatter.Process method is not the same as the one that it accepted.
|
// EntryFormatter.Process method is not the same as the one that it accepted.
|
||||||
func TestEntryFormatter_Process_NoMutation(t *testing.T) {
|
func TestEntryFormatter_Process_NoMutation(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
// Create the formatter node.
|
// Create the formatter node.
|
||||||
cfg, err := NewFormatterConfig()
|
cfg, err := NewFormatterConfig()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -5,10 +5,42 @@ package audit
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/internal/observability/event"
|
"github.com/hashicorp/vault/internal/observability/event"
|
||||||
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// version defines the version of audit events.
|
||||||
|
const version = "v0.1"
|
||||||
|
|
||||||
|
// Audit subtypes.
|
||||||
|
const (
|
||||||
|
RequestType subtype = "AuditRequest"
|
||||||
|
ResponseType subtype = "AuditResponse"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Audit formats.
|
||||||
|
const (
|
||||||
|
JSONFormat format = "json"
|
||||||
|
JSONxFormat format = "jsonx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AuditEvent is the audit event.
|
||||||
|
type AuditEvent struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Subtype subtype `json:"subtype"` // the subtype of the audit event.
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
Data *logical.LogInput `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// format defines types of format audit events support.
|
||||||
|
type format string
|
||||||
|
|
||||||
|
// subtype defines the type of audit event.
|
||||||
|
type subtype string
|
||||||
|
|
||||||
// NewEvent should be used to create an audit event. The subtype field is needed
|
// NewEvent should be used to create an audit event. The subtype field is needed
|
||||||
// for audit events. It will generate an ID if no ID is supplied. Supported
|
// for audit events. It will generate an ID if no ID is supplied. Supported
|
||||||
// options: WithID, WithNow.
|
// options: WithID, WithNow.
|
||||||
@@ -99,13 +131,14 @@ func (f format) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MetricTag returns a tag corresponding to this subtype to include in metrics.
|
// MetricTag returns a tag corresponding to this subtype to include in metrics.
|
||||||
func (st subtype) MetricTag() string {
|
// If a tag cannot be found the value is returned 'as-is' in string format.
|
||||||
switch st {
|
func (t subtype) MetricTag() string {
|
||||||
|
switch t {
|
||||||
case RequestType:
|
case RequestType:
|
||||||
return "log_request"
|
return "log_request"
|
||||||
case ResponseType:
|
case ResponseType:
|
||||||
return "log_response"
|
return "log_response"
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return string(t)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import (
|
|||||||
|
|
||||||
// TestAuditEvent_new exercises the newEvent func to create audit events.
|
// TestAuditEvent_new exercises the newEvent func to create audit events.
|
||||||
func TestAuditEvent_new(t *testing.T) {
|
func TestAuditEvent_new(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Options []Option
|
Options []Option
|
||||||
Subtype subtype
|
Subtype subtype
|
||||||
@@ -107,6 +109,8 @@ func TestAuditEvent_new(t *testing.T) {
|
|||||||
|
|
||||||
// TestAuditEvent_Validate exercises the validation for an audit event.
|
// TestAuditEvent_Validate exercises the validation for an audit event.
|
||||||
func TestAuditEvent_Validate(t *testing.T) {
|
func TestAuditEvent_Validate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value *AuditEvent
|
Value *AuditEvent
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -198,6 +202,8 @@ func TestAuditEvent_Validate(t *testing.T) {
|
|||||||
|
|
||||||
// TestAuditEvent_Validate_Subtype exercises the validation for an audit event's subtype.
|
// TestAuditEvent_Validate_Subtype exercises the validation for an audit event's subtype.
|
||||||
func TestAuditEvent_Validate_Subtype(t *testing.T) {
|
func TestAuditEvent_Validate_Subtype(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -243,6 +249,8 @@ func TestAuditEvent_Validate_Subtype(t *testing.T) {
|
|||||||
|
|
||||||
// TestAuditEvent_Validate_Format exercises the validation for an audit event's format.
|
// TestAuditEvent_Validate_Format exercises the validation for an audit event's format.
|
||||||
func TestAuditEvent_Validate_Format(t *testing.T) {
|
func TestAuditEvent_Validate_Format(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -285,3 +293,42 @@ func TestAuditEvent_Validate_Format(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAuditEvent_Subtype_MetricTag is used to ensure that we get the string value
|
||||||
|
// we expect for a subtype when we want to use it as a metrics tag.
|
||||||
|
// In some strange scenario where the subtype was never validated, it is technically
|
||||||
|
// possible to get a value that isn't related to request/response, but this shouldn't
|
||||||
|
// really be happening, so we will return it as is.
|
||||||
|
func TestAuditEvent_Subtype_MetricTag(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := map[string]struct {
|
||||||
|
input string
|
||||||
|
expectedOutput string
|
||||||
|
}{
|
||||||
|
"request": {
|
||||||
|
input: "AuditRequest",
|
||||||
|
expectedOutput: "log_request",
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
input: "AuditResponse",
|
||||||
|
expectedOutput: "log_response",
|
||||||
|
},
|
||||||
|
"non-validated": {
|
||||||
|
input: "juan",
|
||||||
|
expectedOutput: "juan",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range tests {
|
||||||
|
name := name
|
||||||
|
tc := tc
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
st := subtype(tc.input)
|
||||||
|
tag := st.MetricTag()
|
||||||
|
require.Equal(t, tc.expectedOutput, tag)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ func TestProcessManual_NilData(t *testing.T) {
|
|||||||
// TestProcessManual_BadIDs tests ProcessManual when different bad values are
|
// TestProcessManual_BadIDs tests ProcessManual when different bad values are
|
||||||
// supplied for the ID parameter.
|
// supplied for the ID parameter.
|
||||||
func TestProcessManual_BadIDs(t *testing.T) {
|
func TestProcessManual_BadIDs(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
IDs []eventlogger.NodeID
|
IDs []eventlogger.NodeID
|
||||||
ExpectedErrorMessage string
|
ExpectedErrorMessage string
|
||||||
|
|||||||
@@ -10,6 +10,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Option is how options are passed as arguments.
|
||||||
|
type Option func(*options) error
|
||||||
|
|
||||||
|
// options are used to represent configuration for a audit related nodes.
|
||||||
|
type options struct {
|
||||||
|
withID string
|
||||||
|
withNow time.Time
|
||||||
|
withSubtype subtype
|
||||||
|
withFormat format
|
||||||
|
withPrefix string
|
||||||
|
withRaw bool
|
||||||
|
withElision bool
|
||||||
|
withOmitTime bool
|
||||||
|
withHMACAccessor bool
|
||||||
|
withHeaderFormatter HeaderFormatter
|
||||||
|
}
|
||||||
|
|
||||||
// getDefaultOptions returns options with their default values.
|
// getDefaultOptions returns options with their default values.
|
||||||
func getDefaultOptions() options {
|
func getDefaultOptions() options {
|
||||||
return options{
|
return options{
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
|
|
||||||
// TestOptions_WithFormat exercises WithFormat Option to ensure it performs as expected.
|
// TestOptions_WithFormat exercises WithFormat Option to ensure it performs as expected.
|
||||||
func TestOptions_WithFormat(t *testing.T) {
|
func TestOptions_WithFormat(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -68,6 +70,8 @@ func TestOptions_WithFormat(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithSubtype exercises WithSubtype Option to ensure it performs as expected.
|
// TestOptions_WithSubtype exercises WithSubtype Option to ensure it performs as expected.
|
||||||
func TestOptions_WithSubtype(t *testing.T) {
|
func TestOptions_WithSubtype(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -113,6 +117,8 @@ func TestOptions_WithSubtype(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithNow exercises WithNow Option to ensure it performs as expected.
|
// TestOptions_WithNow exercises WithNow Option to ensure it performs as expected.
|
||||||
func TestOptions_WithNow(t *testing.T) {
|
func TestOptions_WithNow(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value time.Time
|
Value time.Time
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -154,6 +160,8 @@ func TestOptions_WithNow(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithID exercises WithID Option to ensure it performs as expected.
|
// TestOptions_WithID exercises WithID Option to ensure it performs as expected.
|
||||||
func TestOptions_WithID(t *testing.T) {
|
func TestOptions_WithID(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -199,6 +207,8 @@ func TestOptions_WithID(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithPrefix exercises WithPrefix Option to ensure it performs as expected.
|
// TestOptions_WithPrefix exercises WithPrefix Option to ensure it performs as expected.
|
||||||
func TestOptions_WithPrefix(t *testing.T) {
|
func TestOptions_WithPrefix(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value string
|
Value string
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
@@ -244,6 +254,8 @@ func TestOptions_WithPrefix(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithRaw exercises WithRaw Option to ensure it performs as expected.
|
// TestOptions_WithRaw exercises WithRaw Option to ensure it performs as expected.
|
||||||
func TestOptions_WithRaw(t *testing.T) {
|
func TestOptions_WithRaw(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value bool
|
Value bool
|
||||||
ExpectedValue bool
|
ExpectedValue bool
|
||||||
@@ -274,6 +286,8 @@ func TestOptions_WithRaw(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithElision exercises WithElision Option to ensure it performs as expected.
|
// TestOptions_WithElision exercises WithElision Option to ensure it performs as expected.
|
||||||
func TestOptions_WithElision(t *testing.T) {
|
func TestOptions_WithElision(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value bool
|
Value bool
|
||||||
ExpectedValue bool
|
ExpectedValue bool
|
||||||
@@ -304,6 +318,8 @@ func TestOptions_WithElision(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithHMACAccessor exercises WithHMACAccessor Option to ensure it performs as expected.
|
// TestOptions_WithHMACAccessor exercises WithHMACAccessor Option to ensure it performs as expected.
|
||||||
func TestOptions_WithHMACAccessor(t *testing.T) {
|
func TestOptions_WithHMACAccessor(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value bool
|
Value bool
|
||||||
ExpectedValue bool
|
ExpectedValue bool
|
||||||
@@ -334,6 +350,8 @@ func TestOptions_WithHMACAccessor(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_WithOmitTime exercises WithOmitTime Option to ensure it performs as expected.
|
// TestOptions_WithOmitTime exercises WithOmitTime Option to ensure it performs as expected.
|
||||||
func TestOptions_WithOmitTime(t *testing.T) {
|
func TestOptions_WithOmitTime(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value bool
|
Value bool
|
||||||
ExpectedValue bool
|
ExpectedValue bool
|
||||||
@@ -365,6 +383,8 @@ func TestOptions_WithOmitTime(t *testing.T) {
|
|||||||
// TestOptions_WithHeaderFormatter exercises the WithHeaderFormatter Option to
|
// TestOptions_WithHeaderFormatter exercises the WithHeaderFormatter Option to
|
||||||
// ensure it applies the option as expected under various circumstances.
|
// ensure it applies the option as expected under various circumstances.
|
||||||
func TestOptions_WithHeaderFormatter(t *testing.T) {
|
func TestOptions_WithHeaderFormatter(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
Value HeaderFormatter
|
Value HeaderFormatter
|
||||||
ExpectedValue HeaderFormatter
|
ExpectedValue HeaderFormatter
|
||||||
@@ -403,6 +423,8 @@ func TestOptions_WithHeaderFormatter(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_Default exercises getDefaultOptions to assert the default values.
|
// TestOptions_Default exercises getDefaultOptions to assert the default values.
|
||||||
func TestOptions_Default(t *testing.T) {
|
func TestOptions_Default(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
opts := getDefaultOptions()
|
opts := getDefaultOptions()
|
||||||
require.NotNil(t, opts)
|
require.NotNil(t, opts)
|
||||||
require.True(t, time.Now().After(opts.withNow))
|
require.True(t, time.Now().After(opts.withNow))
|
||||||
@@ -411,6 +433,8 @@ func TestOptions_Default(t *testing.T) {
|
|||||||
|
|
||||||
// TestOptions_Opts exercises GetOpts with various Option values.
|
// TestOptions_Opts exercises GetOpts with various Option values.
|
||||||
func TestOptions_Opts(t *testing.T) {
|
func TestOptions_Opts(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
opts []Option
|
opts []Option
|
||||||
IsErrorExpected bool
|
IsErrorExpected bool
|
||||||
|
|||||||
@@ -6,61 +6,12 @@ package audit
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-bexpr"
|
|
||||||
"github.com/hashicorp/vault/internal/observability/event"
|
"github.com/hashicorp/vault/internal/observability/event"
|
||||||
"github.com/hashicorp/vault/sdk/helper/salt"
|
"github.com/hashicorp/vault/sdk/helper/salt"
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Audit subtypes.
|
|
||||||
const (
|
|
||||||
RequestType subtype = "AuditRequest"
|
|
||||||
ResponseType subtype = "AuditResponse"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Audit formats.
|
|
||||||
const (
|
|
||||||
JSONFormat format = "json"
|
|
||||||
JSONxFormat format = "jsonx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// version defines the version of audit events.
|
|
||||||
const version = "v0.1"
|
|
||||||
|
|
||||||
// subtype defines the type of audit event.
|
|
||||||
type subtype string
|
|
||||||
|
|
||||||
// format defines types of format audit events support.
|
|
||||||
type format string
|
|
||||||
|
|
||||||
// AuditEvent is the audit event.
|
|
||||||
type AuditEvent struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Subtype subtype `json:"subtype"` // the subtype of the audit event.
|
|
||||||
Timestamp time.Time `json:"timestamp"`
|
|
||||||
Data *logical.LogInput `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option is how options are passed as arguments.
|
|
||||||
type Option func(*options) error
|
|
||||||
|
|
||||||
// options are used to represent configuration for a audit related nodes.
|
|
||||||
type options struct {
|
|
||||||
withID string
|
|
||||||
withNow time.Time
|
|
||||||
withSubtype subtype
|
|
||||||
withFormat format
|
|
||||||
withPrefix string
|
|
||||||
withRaw bool
|
|
||||||
withElision bool
|
|
||||||
withOmitTime bool
|
|
||||||
withHMACAccessor bool
|
|
||||||
withHeaderFormatter HeaderFormatter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Salter is an interface that provides a way to obtain a Salt for hashing.
|
// Salter is an interface that provides a way to obtain a Salt for hashing.
|
||||||
type Salter interface {
|
type Salter interface {
|
||||||
// Salt returns a non-nil salt or an error.
|
// Salt returns a non-nil salt or an error.
|
||||||
@@ -94,14 +45,6 @@ type HeaderFormatter interface {
|
|||||||
ApplyConfig(context.Context, map[string][]string, Salter) (map[string][]string, error)
|
ApplyConfig(context.Context, map[string][]string, Salter) (map[string][]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EntryFormatter should be used to format audit requests and responses.
|
|
||||||
type EntryFormatter struct {
|
|
||||||
salter Salter
|
|
||||||
headerFormatter HeaderFormatter
|
|
||||||
config FormatterConfig
|
|
||||||
prefix string
|
|
||||||
}
|
|
||||||
|
|
||||||
// EntryFormatterWriter should be used to format and write out audit requests and responses.
|
// EntryFormatterWriter should be used to format and write out audit requests and responses.
|
||||||
type EntryFormatterWriter struct {
|
type EntryFormatterWriter struct {
|
||||||
Formatter
|
Formatter
|
||||||
@@ -144,13 +87,6 @@ type FormatterConfig struct {
|
|||||||
RequiredFormat format
|
RequiredFormat format
|
||||||
}
|
}
|
||||||
|
|
||||||
// EntryFilter should be used to filter audit requests and responses which should
|
|
||||||
// make it to a sink.
|
|
||||||
type EntryFilter struct {
|
|
||||||
// the evaluator for the bexpr expression that should be applied by the node.
|
|
||||||
evaluator *bexpr.Evaluator
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestEntry is the structure of a request audit log entry.
|
// RequestEntry is the structure of a request audit log entry.
|
||||||
type RequestEntry struct {
|
type RequestEntry struct {
|
||||||
Time string `json:"time,omitempty"`
|
Time string `json:"time,omitempty"`
|
||||||
|
|||||||
Reference in New Issue
Block a user