diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 08141a2b946..51714255d35 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -16,42 +16,26 @@ jobs:
steps:
- name: Check out code into the Go module directory
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- - uses: actions/setup-go@v2
+ - uses: actions/setup-go@v3
with:
go-version: '^1.19'
- run: go version
-# - uses: actions/cache@v2
-# with:
-# # In order:
-# # * Module download cache
-# # * Build cache (Linux)
-# # * Build cache (Mac)
-# # * Build cache (Windows)
-# path: |
-# ~/go/pkg/mod
-# ~/.cache/go-build
-# ~/Library/Caches/go-build
-# %LocalAppData%\go-build
-# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-# restore-keys: |
-# ${{ runner.os }}-go-
-
- name: Get dependencies
run: |
go get -v -t -d ./...
sudo apt-get install mingw-w64-x86-64-dev gcc-mingw-w64-x86-64 gcc-mingw-w64
- name: Use Node.js v16
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
node-version: 16
- name: Cache node-modules
- uses: actions/cache@v2
+ uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
@@ -82,7 +66,7 @@ jobs:
go run make.go -v DarwinBase
- name: StoreBinaries
- uses: actions/upload-artifact@v1
+ uses: actions/upload-artifact@v3
with:
name: Binaries
path: output
diff --git a/.github/workflows/musl.yaml b/.github/workflows/musl.yaml
index 44fd6ff3f2d..03a22404999 100644
--- a/.github/workflows/musl.yaml
+++ b/.github/workflows/musl.yaml
@@ -12,9 +12,9 @@ jobs:
steps:
- name: Check out code into the Go module directory
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- - uses: actions/setup-go@v2
+ - uses: actions/setup-go@v3
with:
go-version: '^1.19'
@@ -35,7 +35,7 @@ jobs:
cd ..
- name: Use Node.js v16
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
node-version: 16
@@ -53,7 +53,7 @@ jobs:
go run make.go -v LinuxMusl
- name: StoreBinaries
- uses: actions/upload-artifact@v1
+ uses: actions/upload-artifact@v3
with:
name: Binaries
path: output
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index e0ff65acc15..302571975eb 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -6,29 +6,13 @@ jobs:
runs-on: windows-2019
steps:
- name: Set up Go 1.19
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
with:
go-version: 1.19
id: go
-# - uses: actions/cache@v2
-# with:
- # In order:
- # * Module download cache
- # * Build cache (Linux)
- # * Build cache (Mac)
- # * Build cache (Windows)
-# path: |
-# ~/go/pkg/mod
-# ~/.cache/go-build
-# ~/Library/Caches/go-build
-# %LocalAppData%\go-build
-# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-# restore-keys: |
-# ${{ runner.os }}-go-
-
- name: Check out code into the Go module directory
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Configure test environment
shell: cmd
@@ -123,7 +107,7 @@ jobs:
mkdir -p artifact_output/server/
cp artifacts/testdata/server/testcases/*.out* artifact_output/server/
- - uses: actions/upload-artifact@master
+ - uses: actions/upload-artifact@v3
if: always()
with:
name: artifact
diff --git a/accessors/vql_arg_parser.go b/accessors/vql_arg_parser.go
index 2c3fb9895fc..94faac00365 100644
--- a/accessors/vql_arg_parser.go
+++ b/accessors/vql_arg_parser.go
@@ -70,33 +70,6 @@ func parseOSPath(ctx context.Context,
// Initializer can be a list of components. In this case we
// take the base pathspec (which is accessor determined) and
// add the components to it.
- case []types.Any:
- components := make([]string, 0, len(t))
- for _, i := range t {
- i_str, ok := i.(string)
- if ok {
- components = append(components, i_str)
- }
- }
-
- // Build a pathspec from the accessor and the components.
- base, err := accessor.ParsePath("")
- if err != nil {
- return nil, err
- }
-
- base.Components = append(base.Components, components...)
- return base, nil
-
- case []string:
- // Build a pathspec from the accessor and the components.
- base, err := accessor.ParsePath("")
- if err != nil {
- return nil, err
- }
-
- base.Components = append(base.Components, t...)
- return base, nil
case string:
return accessor.ParsePath(t)
@@ -105,6 +78,28 @@ func parseOSPath(ctx context.Context,
return accessor.ParsePath(string(t))
default:
+ result, _ := accessor.ParsePath("")
+
+ // Is it an array? Generic code to handle arrays - just append
+ // each element together to form a single path. This allows
+ // joining components directly:
+ // ["bin", "ls"] or ["/usr/bin", "ls"]
+ a_value := reflect.Indirect(reflect.ValueOf(value))
+ if a_value.Type().Kind() == reflect.Slice {
+ for idx := 0; idx < a_value.Len(); idx++ {
+ item, err := parseOSPath(ctx, scope, args,
+ a_value.Index(int(idx)).Interface())
+ if err != nil {
+ continue
+ }
+ item_os_path, ok := item.(*OSPath)
+ if ok {
+ result = result.Append(item_os_path.Components...)
+ }
+ }
+ return result, nil
+ }
+
// This is a fatal error on the client.
return nil, fmt.Errorf("Expecting a path arg type, not %T", t)
}
diff --git a/api/api.go b/api/api.go
index b7821589181..14951e85534 100644
--- a/api/api.go
+++ b/api/api.go
@@ -290,7 +290,7 @@ func (self *ApiServer) NotifyClients(
if in.ClientId != "" {
self.server_obj.Info("sending notification to %s", in.ClientId)
- err = notifier.NotifyListener(org_config_obj, in.ClientId,
+ err = notifier.NotifyListener(ctx, org_config_obj, in.ClientId,
"API.NotifyClients")
} else {
return nil, status.Error(codes.InvalidArgument,
@@ -694,7 +694,7 @@ func (self *ApiServer) GetArtifacts(
}
for _, name := range in.Names {
- artifact, pres := repository.Get(org_config_obj, name)
+ artifact, pres := repository.Get(ctx, org_config_obj, name)
if pres {
result.Items = append(result.Items, artifact)
}
@@ -734,7 +734,7 @@ func (self *ApiServer) GetArtifactFile(
"User is not allowed to view custom artifacts.")
}
- artifact, err := getArtifactFile(org_config_obj, in.Name)
+ artifact, err := getArtifactFile(ctx, org_config_obj, in.Name)
if err != nil {
return nil, Status(self.verbose, err)
}
@@ -787,7 +787,7 @@ func (self *ApiServer) SetArtifactFile(
"User is not allowed to modify artifacts (%v).", permissions))
}
- definition, err := setArtifactFile(org_config_obj, principal, in, "")
+ definition, err := setArtifactFile(ctx, org_config_obj, principal, in, "")
if err != nil {
message := &api_proto.APIResponse{
Error: true,
diff --git a/api/artifacts.go b/api/artifacts.go
index f11dfbe55f0..42f17fdd9ae 100644
--- a/api/artifacts.go
+++ b/api/artifacts.go
@@ -67,7 +67,7 @@ sources:
)
func getArtifactFile(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
name string) (string, error) {
manager, err := services.GetRepositoryManager(config_obj)
@@ -80,7 +80,7 @@ func getArtifactFile(
return "", err
}
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if !pres {
return default_artifact, nil
}
@@ -107,9 +107,9 @@ func ensureArtifactPrefix(definition, prefix string) string {
})
}
-func setArtifactFile(config_obj *config_proto.Config, principal string,
- in *api_proto.SetArtifactRequest,
- required_prefix string) (
+func setArtifactFile(
+ ctx context.Context, config_obj *config_proto.Config, principal string,
+ in *api_proto.SetArtifactRequest, required_prefix string) (
*artifacts_proto.Artifact, error) {
manager, err := services.GetRepositoryManager(config_obj)
@@ -134,11 +134,11 @@ func setArtifactFile(config_obj *config_proto.Config, principal string,
required_prefix + "'")
}
- return artifact_definition, manager.DeleteArtifactFile(config_obj,
+ return artifact_definition, manager.DeleteArtifactFile(ctx, config_obj,
principal, artifact_definition.Name)
case api_proto.SetArtifactRequest_SET:
- return manager.SetArtifactFile(
+ return manager.SetArtifactFile(ctx,
config_obj, principal, in.Artifact, required_prefix)
}
@@ -171,7 +171,7 @@ func getReportArtifacts(
return nil, Status(config_obj.Verbose, err)
}
for _, name := range names {
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if pres {
for _, report := range artifact.Reports {
if report.Type == report_type {
@@ -258,7 +258,7 @@ func searchArtifact(
continue
}
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if pres {
// Skip non matching types
if artifact_type != "" &&
@@ -352,7 +352,7 @@ func (self *ApiServer) LoadArtifactPack(
Artifact: artifact_definition,
}
- definition, err := setArtifactFile(
+ definition, err := setArtifactFile(ctx,
org_config_obj, principal, request, prefix)
if err == nil {
logging.LogAudit(org_config_obj, principal, "LoadArtifactPack",
diff --git a/api/download.go b/api/download.go
index c9355a0f4fb..e0802ed3662 100644
--- a/api/download.go
+++ b/api/download.go
@@ -272,7 +272,7 @@ func getRows(
// We want an event table.
if request.Type == "CLIENT_EVENT" || request.Type == "SERVER_EVENT" {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, request.ClientId, request.FlowId,
request.Artifact)
if err != nil {
@@ -290,7 +290,7 @@ func getRows(
return rs_reader.Rows(ctx), rs_reader.Close, log_path, err
} else {
- log_path, err := tables.GetPathSpec(config_obj, request)
+ log_path, err := tables.GetPathSpec(ctx, config_obj, request)
if err != nil {
return nil, nil, nil, err
}
@@ -314,9 +314,10 @@ func getTransformer(
client_id := utils.GetString(row, "ClientId")
flow_id := utils.GetString(row, "FlowId")
- flow, err := flows.LoadCollectionContext(config_obj, client_id, flow_id)
+ flow, err := flows.LoadCollectionContext(
+ ctx, config_obj, client_id, flow_id)
if err != nil {
- flow = flows.NewCollectionContext(config_obj)
+ flow = flows.NewCollectionContext(ctx, config_obj)
}
return ordereddict.NewDict().
diff --git a/api/events.go b/api/events.go
index d72b254241c..b28f164fd77 100644
--- a/api/events.go
+++ b/api/events.go
@@ -69,7 +69,7 @@ func (self *ApiServer) PushEvents(
// only broadcast the events for local listeners. Minions
// write the events themselves, so we just need to broadcast
// for any server event artifacts that occur.
- journal.Broadcast(org_config_obj,
+ journal.Broadcast(ctx, org_config_obj,
rows, in.Artifact, in.ClientId, in.FlowId)
return &emptypb.Empty{}, err
}
@@ -127,7 +127,7 @@ func (self *ApiServer) WriteEvent(
return nil, Status(self.verbose, err)
}
- err = journal.PushRowsToArtifact(org_config_obj,
+ err = journal.PushRowsToArtifact(ctx, org_config_obj,
rows, in.Query.Name, user_name, "")
return &emptypb.Empty{}, err
}
diff --git a/api/reflect.go b/api/reflect.go
index 1062260597a..2525616d9ed 100644
--- a/api/reflect.go
+++ b/api/reflect.go
@@ -123,7 +123,7 @@ func (self *ApiServer) GetKeywordCompletions(
}
for _, name := range names {
- artifact, pres := repository.Get(org_config_obj, name)
+ artifact, pres := repository.Get(ctx, org_config_obj, name)
if !pres {
continue
}
diff --git a/api/reports.go b/api/reports.go
index 591e6e0b471..36c7cb184aa 100644
--- a/api/reports.go
+++ b/api/reports.go
@@ -61,9 +61,10 @@ func getReport(ctx context.Context,
var template_data string
if in.Type == "" {
- definition, pres := repository.Get(config_obj, "Custom."+in.Artifact)
+ definition, pres := repository.Get(
+ ctx, config_obj, "Custom."+in.Artifact)
if !pres {
- definition, pres = repository.Get(config_obj, in.Artifact)
+ definition, pres = repository.Get(ctx, config_obj, in.Artifact)
}
if pres {
for _, report := range definition.Reports {
@@ -105,7 +106,7 @@ func getReport(ctx context.Context,
template_engine, in.ClientId, in.StartTime, in.EndTime)
case "ARTIFACT_DESCRIPTION":
- template_data, err = reporting.GenerateArtifactDescriptionReport(
+ template_data, err = reporting.GenerateArtifactDescriptionReport(ctx,
template_engine, config_obj)
}
diff --git a/api/tables/table.go b/api/tables/table.go
index d192f577672..1f073a43598 100644
--- a/api/tables/table.go
+++ b/api/tables/table.go
@@ -76,7 +76,7 @@ func GetTable(
return nil, err
}
- artifact, pres := repository.Get(config_obj, in.Artifact)
+ artifact, pres := repository.Get(ctx, config_obj, in.Artifact)
if pres {
result.ColumnTypes = artifact.ColumnTypes
}
@@ -98,10 +98,10 @@ func getTable(
}
result := &api_proto.GetTableResponse{
- ColumnTypes: getColumnTypes(config_obj, in),
+ ColumnTypes: getColumnTypes(ctx, config_obj, in),
}
- path_spec, err := GetPathSpec(config_obj, in)
+ path_spec, err := GetPathSpec(ctx, config_obj, in)
if err != nil {
return result, err
}
@@ -188,7 +188,7 @@ func getTable(
// The GUI is requesting table data. This function tries to figure out
// the column types.
func getColumnTypes(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
in *api_proto.GetTableRequest) []*artifacts_proto.ColumnType {
// For artifacts column types are specified in the `column_types`
@@ -204,7 +204,7 @@ func getColumnTypes(
return nil
}
- artifact, pres := repository.Get(config_obj, in.Artifact)
+ artifact, pres := repository.Get(ctx, config_obj, in.Artifact)
if pres {
return artifact.ColumnTypes
}
@@ -234,11 +234,11 @@ func getColumnTypes(
// switch to figure out where the result set we want to look at is
// stored.
func GetPathSpec(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
in *api_proto.GetTableRequest) (api.FSPathSpec, error) {
if in.FlowId != "" && in.Artifact != "" {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, in.ClientId, in.FlowId, in.Artifact)
if err != nil {
return nil, err
@@ -289,7 +289,7 @@ func getEventTable(
config_obj *config_proto.Config,
in *api_proto.GetTableRequest) (
*api_proto.GetTableResponse, error) {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, in.ClientId, in.FlowId, in.Artifact)
if err != nil {
return nil, err
@@ -303,7 +303,7 @@ func getEventTableLogs(
config_obj *config_proto.Config,
in *api_proto.GetTableRequest) (
*api_proto.GetTableResponse, error) {
- path_manager, err := artifacts.NewArtifactLogPathManager(
+ path_manager, err := artifacts.NewArtifactLogPathManager(ctx,
config_obj, in.ClientId, "", in.Artifact)
if err != nil {
return nil, err
diff --git a/api/tools.go b/api/tools.go
index 7724bb22425..4bc598f9fb5 100644
--- a/api/tools.go
+++ b/api/tools.go
@@ -34,7 +34,7 @@ func (self *ApiServer) GetToolInfo(ctx context.Context,
return inventory.GetToolInfo(ctx, org_config_obj, in.Name)
}
- return inventory.ProbeToolInfo(in.Name)
+ return inventory.ProbeToolInfo(ctx, org_config_obj, in.Name)
}
func (self *ApiServer) SetToolInfo(ctx context.Context,
@@ -64,7 +64,7 @@ func (self *ApiServer) SetToolInfo(ctx context.Context,
return nil, Status(self.verbose, err)
}
- err = inventory.AddTool(org_config_obj, in,
+ err = inventory.AddTool(ctx, org_config_obj, in,
services.ToolOptions{
AdminOverride: true,
})
diff --git a/api/upload.go b/api/upload.go
index c7c1c63c203..999ba339525 100644
--- a/api/upload.go
+++ b/api/upload.go
@@ -125,7 +125,8 @@ func toolUploadHandler() http.Handler {
return
}
- err = inventory.AddTool(org_config_obj, tool,
+ ctx := r.Context()
+ err = inventory.AddTool(ctx, org_config_obj, tool,
services.ToolOptions{
AdminOverride: true,
})
diff --git a/artifacts/definitions/Generic/Collectors/File.yaml b/artifacts/definitions/Generic/Collectors/File.yaml
index 7dc0829698f..84c1b35a974 100755
--- a/artifacts/definitions/Generic/Collectors/File.yaml
+++ b/artifacts/definitions/Generic/Collectors/File.yaml
@@ -16,17 +16,25 @@ parameters:
default: |
Glob
Users\*\NTUser.dat
+
- name: Root
description: |
On Windows, this is the device to apply all the glob on
(e.g. `C:`). On *NIX, this should be a path to a subdirectory or
/.
default: "C:"
+
- name: Accessor
default: auto
description: |
On Windows, this can be changed to `ntfs`.
+ - name: NTFS_CACHE_TIME
+ type: int
+ description: How often to flush the NTFS cache. (Default is never).
+ default: "1000000"
+
+
sources:
- name: All Matches Metadata
query: |
diff --git a/artifacts/proto/artifact.pb.go b/artifacts/proto/artifact.pb.go
index dd1e7496b40..bd6339bcecb 100644
--- a/artifacts/proto/artifact.pb.go
+++ b/artifacts/proto/artifact.pb.go
@@ -796,6 +796,10 @@ type Tool struct {
Hash string `protobuf:"bytes,6,opt,name=hash,proto3" json:"hash,omitempty"`
// If set on a request we refresh the hash.
Materialize bool `protobuf:"varint,11,opt,name=materialize,proto3" json:"materialize,omitempty"`
+ // The artifact this definition came from.
+ Artifact string `protobuf:"bytes,13,opt,name=artifact,proto3" json:"artifact,omitempty"`
+ // Additional versions of this tool.
+ Versions []*Tool `protobuf:"bytes,14,rep,name=versions,proto3" json:"versions,omitempty"`
}
func (x *Tool) Reset() {
@@ -914,6 +918,20 @@ func (x *Tool) GetMaterialize() bool {
return false
}
+func (x *Tool) GetArtifact() string {
+ if x != nil {
+ return x.Artifact
+ }
+ return ""
+}
+
+func (x *Tool) GetVersions() []*Tool {
+ if x != nil {
+ return x.Versions
+ }
+ return nil
+}
+
// Keep track of all the third party tools we know about.
type ThirdParty struct {
state protoimpl.MessageState
@@ -1294,7 +1312,7 @@ var file_artifact_proto_rawDesc = []byte{
0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x6f, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66,
- 0x61, 0x63, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x82, 0x03, 0x0a, 0x04, 0x54,
+ 0x61, 0x63, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xc7, 0x03, 0x0a, 0x04, 0x54,
0x6f, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x69, 0x74,
@@ -1318,29 +1336,33 @@ var file_artifact_proto_rawDesc = []byte{
0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73,
0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x20, 0x0a,
0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x0b, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x22,
- 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x79, 0x12, 0x21,
- 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c,
- 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcc, 0x01, 0x0a, 0x09,
- 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d,
- 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65,
- 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73,
- 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c, 0x6f, 0x70, 0x73,
- 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75,
- 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x63, 0x70,
- 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6f, 0x70, 0x73, 0x5f, 0x6c,
- 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x69, 0x6f, 0x70, 0x73,
- 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77,
- 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73,
- 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62,
- 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x55,
- 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x37, 0x5a, 0x35, 0x77, 0x77,
- 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70,
- 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12,
+ 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x08, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4a, 0x0a, 0x0b, 0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61,
+ 0x72, 0x74, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52,
+ 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x22, 0xcc, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x18,
+ 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x70, 0x73, 0x5f,
+ 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02,
+ 0x52, 0x0c, 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x1b,
+ 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x02, 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69,
+ 0x6f, 0x70, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52,
+ 0x09, 0x69, 0x6f, 0x70, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61,
+ 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61,
+ 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c,
+ 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x0e, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42,
+ 0x37, 0x5a, 0x35, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f,
+ 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
+ 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1380,12 +1402,13 @@ var file_artifact_proto_depIdxs = []int32{
5, // 7: proto.Artifact.reports:type_name -> proto.Report
1, // 8: proto.Artifact.column_types:type_name -> proto.ColumnType
6, // 9: proto.ArtifactDescriptors.items:type_name -> proto.Artifact
- 8, // 10: proto.third_party.tools:type_name -> proto.Tool
- 11, // [11:11] is the sub-list for method output_type
- 11, // [11:11] is the sub-list for method input_type
- 11, // [11:11] is the sub-list for extension type_name
- 11, // [11:11] is the sub-list for extension extendee
- 0, // [0:11] is the sub-list for field type_name
+ 8, // 10: proto.Tool.versions:type_name -> proto.Tool
+ 8, // 11: proto.third_party.tools:type_name -> proto.Tool
+ 12, // [12:12] is the sub-list for method output_type
+ 12, // [12:12] is the sub-list for method input_type
+ 12, // [12:12] is the sub-list for extension type_name
+ 12, // [12:12] is the sub-list for extension extendee
+ 0, // [0:12] is the sub-list for field type_name
}
func init() { file_artifact_proto_init() }
diff --git a/artifacts/proto/artifact.proto b/artifacts/proto/artifact.proto
index 1ad9203e39e..9299a1c3a3a 100644
--- a/artifacts/proto/artifact.proto
+++ b/artifacts/proto/artifact.proto
@@ -271,6 +271,13 @@ message Tool {
// If set on a request we refresh the hash.
bool materialize = 11;
+
+ // The artifact this definition came from.
+ string artifact = 13;
+
+ // Additional versions of this tool.
+ repeated Tool versions = 14;
+
}
// Keep track of all the third party tools we know about.
diff --git a/artifacts/testdata/server/testcases/binary_blobs.out.yaml b/artifacts/testdata/server/testcases/binary_blobs.out.yaml
index f2c5e9f6534..97332889117 100644
--- a/artifacts/testdata/server/testcases/binary_blobs.out.yaml
+++ b/artifacts/testdata/server/testcases/binary_blobs.out.yaml
@@ -16,7 +16,9 @@ SELECT * FROM switch( b={SELECT Complete FROM execve(argv=["rm", "-f", "/tmp/aut
"filestore_path": "",
"filename": "winpmem_v3.3.rc3.exe",
"hash": "",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
}
]SELECT * FROM inventory() WHERE name = "WinPmem"[
@@ -32,7 +34,9 @@ SELECT * FROM switch( b={SELECT Complete FROM execve(argv=["rm", "-f", "/tmp/aut
"filestore_path": "351b4f6d59a4266cc7a2eab9cedf959eb6a4c924746044e6edeabdd1a477643e",
"filename": "winpmem_v3.3.rc3.exe",
"hash": "",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
]LET ToolInfo <= dict( Tool_WinPmem_URL="https://github.com/Velocidex/c-aff4/releases/download/v3.3.rc3/winpmem_v3.3.rc3.exe", Tool_WinPmem_FILENAME="winpmem_v3.3.rc3.exe", Tool_WinPmem_HASH="319f6c714d682505157cf72aa928c94ada3c839fb8eb0e503d8770624e897318")[]SELECT DownloadStatus, Hash FROM Artifact.Generic.Utils.FetchBinary( ToolName="WinPmem", SleepDuration=0, ToolInfo=ToolInfo)[
{
diff --git a/artifacts/testdata/server/testcases/tools.out.yaml b/artifacts/testdata/server/testcases/tools.out.yaml
index 33adec57686..065ec161db1 100644
--- a/artifacts/testdata/server/testcases/tools.out.yaml
+++ b/artifacts/testdata/server/testcases/tools.out.yaml
@@ -12,7 +12,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"filestore_path": "",
"filename": "autorunsc_x64.exe",
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
}
]SELECT inventory_get(tool='Autorun_amd64') FROM scope()[
@@ -37,7 +39,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"filestore_path": "",
"filename": "autorunsc_x64.exe",
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
}
]SELECT inventory_get(tool='Autorun_amd64') FROM scope()[
@@ -62,7 +66,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"filestore_path": "1c21ee4d8609f81482dc0a78c641e4586488a9fd562ee28eec25e448a9d0b2e1",
"filename": "yara_test.txt",
"hash": "f03278c10a41adcc97f24a612a680e7aa43efb461b337fef3d2a3d47b51e77bb",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
}
]SELECT inventory_get(tool="FooBar") FROM scope()[
diff --git a/artifacts/testdata/windows/autoexec.out.yaml b/artifacts/testdata/windows/autoexec.out.yaml
index c767698847d..22f00a503e1 100644
--- a/artifacts/testdata/windows/autoexec.out.yaml
+++ b/artifacts/testdata/windows/autoexec.out.yaml
@@ -12,7 +12,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"filestore_path": "",
"filename": "autorunsc_x64.exe",
"hash": "5f4cdd5cbc5aea49e007e35550eaac89a68efc409683730c722f6dd378ba81e9",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
},
"inventory_add(tool='Autorun_x86', url='https://storage.googleapis.com/go.velocidex.com/autorunsc.exe', hash='5f4cdd5cbc5aea49e007e35550eaac89a68efc409683730c722f6dd378ba81e9', filename='autorunsc_x86.exe')": {
"name": "Autorun_x86",
@@ -26,7 +28,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"filestore_path": "",
"filename": "autorunsc_x86.exe",
"hash": "5f4cdd5cbc5aea49e007e35550eaac89a68efc409683730c722f6dd378ba81e9",
- "materialize": false
+ "materialize": false,
+ "artifact": "",
+ "versions": []
}
}
]SELECT Company FROM Artifact.Windows.Sysinternals.Autoruns( All=FALSE, `Boot execute`=TRUE, ToolInfo=inventory_get(tool='Autorun_amd64')) WHERE Company =~ 'Microsoft' LIMIT 1[
diff --git a/bin/artifacts.go b/bin/artifacts.go
index 9d1bdfc3f38..4278c778271 100644
--- a/bin/artifacts.go
+++ b/bin/artifacts.go
@@ -302,7 +302,7 @@ func doArtifactShow() error {
return err
}
- artifact, pres := repository.Get(config_obj, *artifact_command_show_name)
+ artifact, pres := repository.Get(ctx, config_obj, *artifact_command_show_name)
if !pres {
return fmt.Errorf("Artifact %s not found",
*artifact_command_show_name)
@@ -365,7 +365,7 @@ func doArtifactList() error {
continue
}
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if !pres {
return fmt.Errorf("Artifact %s not found", name)
}
diff --git a/bin/tools.go b/bin/tools.go
index dfc11ddf559..ca5984d2e86 100644
--- a/bin/tools.go
+++ b/bin/tools.go
@@ -83,7 +83,8 @@ func doThirdPartyShow() error {
}
fmt.Println(string(serialized))
} else {
- tool, err := inventory_manager.ProbeToolInfo(*third_party_show_file)
+ tool, err := inventory_manager.ProbeToolInfo(
+ ctx, config_obj, *third_party_show_file)
if err != nil {
return fmt.Errorf("Tool not found: %w", err)
}
@@ -197,7 +198,7 @@ func doThirdPartyUpload() error {
return err
}
- err = inventory_manager.AddTool(
+ err = inventory_manager.AddTool(ctx,
config_obj, tool, services.ToolOptions{
AdminOverride: true,
})
diff --git a/file_store/directory/queue_test.go b/file_store/directory/queue_test.go
index cc9bf68e5be..48ebabe1f4c 100644
--- a/file_store/directory/queue_test.go
+++ b/file_store/directory/queue_test.go
@@ -94,7 +94,7 @@ func (self *TestSuite) TestQueueManager() {
FileBufferLeaseSize: 1,
})
- path_manager, err := artifacts.NewArtifactPathManager(self.ConfigObj,
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx, self.ConfigObj,
"C.123", "", "TestQueue")
assert.NoError(self.T(), err)
@@ -163,7 +163,7 @@ func (self *TestSuite) TestQueueManagerJsonl() {
manager := directory.NewDirectoryQueueManager(
self.ConfigObj, file_store).(*directory.DirectoryQueueManager)
- path_manager, err := artifacts.NewArtifactPathManager(self.ConfigObj,
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx, self.ConfigObj,
"C.123", "", "TestQueue")
assert.NoError(self.T(), err)
diff --git a/flows/artifacts.go b/flows/artifacts.go
index c370c11b2fd..4fce0c143d5 100644
--- a/flows/artifacts.go
+++ b/flows/artifacts.go
@@ -96,7 +96,8 @@ type CollectionContext struct {
send_update bool
}
-func NewCollectionContext(config_obj *config_proto.Config) *CollectionContext {
+func NewCollectionContext(
+ ctx context.Context, config_obj *config_proto.Config) *CollectionContext {
self := &CollectionContext{
ArtifactCollectorContext: flows_proto.ArtifactCollectorContext{},
monitoring_batch: make(map[string]*jsonBatch),
@@ -129,7 +130,7 @@ func NewCollectionContext(config_obj *config_proto.Config) *CollectionContext {
journal, err := services.GetJournal(config_obj)
if err == nil {
- journal.PushRowsToArtifactAsync(
+ journal.PushRowsToArtifactAsync(ctx,
config_obj, row, "System.Flow.Completion")
}
})
@@ -226,7 +227,7 @@ func closeContext(
}
if len(collection_context.Logs) > 0 {
- err := flushContextLogs(
+ err := flushContextLogs(ctx,
config_obj, collection_context, collection_context.completer)
if err != nil {
collection_context.State = flows_proto.ArtifactCollectorContext_ERROR
@@ -246,7 +247,7 @@ func closeContext(
}
if len(collection_context.monitoring_batch) > 0 {
- err = flushMonitoringLogs(config_obj, collection_context)
+ err = flushMonitoringLogs(ctx, config_obj, collection_context)
if err != nil {
collection_context.State = flows_proto.ArtifactCollectorContext_ERROR
collection_context.Status = err.Error()
@@ -309,11 +310,11 @@ func flushContextUploadedFiles(
// Load the collector context from storage.
func LoadCollectionContext(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
client_id, flow_id string) (*CollectionContext, error) {
if flow_id == constants.MONITORING_WELL_KNOWN_FLOW {
- result := NewCollectionContext(config_obj)
+ result := NewCollectionContext(ctx, config_obj)
result.SessionId = flow_id
result.ClientId = client_id
@@ -321,7 +322,7 @@ func LoadCollectionContext(
}
flow_path_manager := paths.NewFlowPathManager(client_id, flow_id)
- collection_context := NewCollectionContext(config_obj)
+ collection_context := NewCollectionContext(ctx, config_obj)
db, err := datastore.GetDB(config_obj)
if err != nil {
return nil, err
@@ -344,7 +345,7 @@ func LoadCollectionContext(
// Process an incoming message from the client.
func ArtifactCollectorProcessOneMessage(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext,
message *crypto_proto.VeloMessage) error {
@@ -366,7 +367,7 @@ func ArtifactCollectorProcessOneMessage(
// Handle the response depending on the RequestId
switch message.RequestId {
case constants.TransferWellKnownFlowId:
- return appendUploadDataToFile(
+ return appendUploadDataToFile(ctx,
config_obj, collection_context, message)
case constants.ProcessVQLResponses:
@@ -387,7 +388,7 @@ func ArtifactCollectorProcessOneMessage(
rows_written := uint64(0)
if response.Query.Name != "" {
path_manager, err := artifact_paths.NewArtifactPathManager(
- config_obj,
+ ctx, config_obj,
collection_context.Request.ClientId,
collection_context.SessionId,
response.Query.Name)
@@ -484,7 +485,7 @@ func CheckForStatus(
}
func appendUploadDataToFile(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext,
message *crypto_proto.VeloMessage) error {
@@ -607,7 +608,7 @@ func appendUploadDataToFile(
return err
}
- return journal.PushRowsToArtifact(config_obj,
+ return journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{row},
"System.Upload.Completion",
message.Source, collection_context.SessionId,
@@ -723,7 +724,7 @@ func (self *FlowRunner) ProcessSingleMessage(
return invalidClientId
}
- collection_context, err = LoadCollectionContext(
+ collection_context, err = LoadCollectionContext(ctx,
self.config_obj, job.Source, job.SessionId)
if err != nil {
// Ignore logs and status messages from the
@@ -770,7 +771,8 @@ func (self *FlowRunner) ProcessSingleMessage(
}
if job.SessionId == constants.MONITORING_WELL_KNOWN_FLOW {
- err := MonitoringProcessMessage(self.config_obj, collection_context, job)
+ err := MonitoringProcessMessage(
+ ctx, self.config_obj, collection_context, job)
if err != nil {
Log(self.config_obj, collection_context,
fmt.Sprintf("MonitoringProcessMessage: %v", err))
@@ -778,7 +780,7 @@ func (self *FlowRunner) ProcessSingleMessage(
return err
}
- err := ArtifactCollectorProcessOneMessage(
+ err := ArtifactCollectorProcessOneMessage(ctx,
self.config_obj, collection_context, job)
if err != nil {
Log(self.config_obj, collection_context,
diff --git a/flows/artifacts_test.go b/flows/artifacts_test.go
index 44c90625839..1f530be08f4 100644
--- a/flows/artifacts_test.go
+++ b/flows/artifacts_test.go
@@ -204,7 +204,7 @@ func (self *TestSuite) TestRetransmission() {
runner.Close(context.Background())
// Load the collection context and see what happened.
- collection_context, err := LoadCollectionContext(self.ConfigObj,
+ collection_context, err := LoadCollectionContext(self.Ctx, self.ConfigObj,
self.client_id, flow_id)
assert.NoError(self.T(), err)
@@ -216,8 +216,7 @@ func (self *TestSuite) TestRetransmission() {
func (self *TestSuite) TestResourceLimits() {
manager, err := services.GetRepositoryManager(self.ConfigObj)
assert.NoError(self.T(), err)
- repository, err := manager.GetGlobalRepository(
- self.ConfigObj)
+ repository, err := manager.GetGlobalRepository(self.ConfigObj)
assert.NoError(self.T(), err)
request := &flows_proto.ArtifactCollectorArgs{
@@ -280,7 +279,7 @@ func (self *TestSuite) TestResourceLimits() {
runner.Close(context.Background())
// Load the collection context and see what happened.
- collection_context, err := LoadCollectionContext(self.ConfigObj,
+ collection_context, err := LoadCollectionContext(self.Ctx, self.ConfigObj,
self.client_id, flow_id)
assert.NoError(self.T(), err)
@@ -296,7 +295,7 @@ func (self *TestSuite) TestResourceLimits() {
runner.Close(context.Background())
// Load the collection context and see what happened.
- collection_context, err = LoadCollectionContext(self.ConfigObj,
+ collection_context, err = LoadCollectionContext(self.Ctx, self.ConfigObj,
self.client_id, flow_id)
assert.NoError(self.T(), err)
@@ -314,7 +313,7 @@ func (self *TestSuite) TestResourceLimits() {
runner.Close(context.Background())
// Load the collection context and see what happened.
- collection_context, err = LoadCollectionContext(self.ConfigObj,
+ collection_context, err = LoadCollectionContext(self.Ctx, self.ConfigObj,
self.client_id, flow_id)
assert.NoError(self.T(), err)
@@ -342,7 +341,7 @@ func (self *TestSuite) TestResourceLimits() {
// We still collect these rows but the flow is still in the
// error state. We do this so we dont lose the last few
// messages which are still in flight.
- collection_context, err = LoadCollectionContext(self.ConfigObj,
+ collection_context, err = LoadCollectionContext(self.Ctx, self.ConfigObj,
self.client_id, flow_id)
assert.NoError(self.T(), err)
@@ -375,7 +374,7 @@ func (self *TestSuite) TestClientUploaderStoreFile() {
nilTime, nilTime, nilTime, nilTime, reader)
// Get a new collection context.
- collection_context := NewCollectionContext(self.ConfigObj)
+ collection_context := NewCollectionContext(self.Ctx, self.ConfigObj)
collection_context.ArtifactCollectorContext = flows_proto.ArtifactCollectorContext{
SessionId: self.flow_id,
ClientId: self.client_id,
@@ -387,7 +386,7 @@ func (self *TestSuite) TestClientUploaderStoreFile() {
for _, response := range resp.Drain.WaitForStatsMessage(self.T()) {
response.Source = self.client_id
- err := ArtifactCollectorProcessOneMessage(
+ err := ArtifactCollectorProcessOneMessage(self.Ctx,
self.ConfigObj, collection_context, response)
assert.NoError(self.T(), err)
}
@@ -437,7 +436,7 @@ func (self *TestSuite) TestClientUploaderStoreFile() {
// Check the System.Upload.Completion event.
artifact_path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj, self.client_id, self.flow_id,
+ self.Ctx, self.ConfigObj, self.client_id, self.flow_id,
"System.Upload.Completion")
assert.NoError(self.T(), err)
@@ -580,7 +579,7 @@ func (self *TestSuite) testCollectionCompletion(
outstanding_requests int64,
requests []*crypto_proto.VeloMessage) *flows_proto.ArtifactCollectorContext {
// Get a new collection context.
- collection_context := NewCollectionContext(self.ConfigObj)
+ collection_context := NewCollectionContext(self.Ctx, self.ConfigObj)
collection_context.ArtifactCollectorContext = flows_proto.ArtifactCollectorContext{
SessionId: self.flow_id,
ClientId: self.client_id,
@@ -661,7 +660,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFile() {
nilTime, nilTime, nilTime, nilTime, reader)
// Get a new collection context.
- collection_context := NewCollectionContext(self.ConfigObj)
+ collection_context := NewCollectionContext(self.Ctx, self.ConfigObj)
collection_context.ArtifactCollectorContext = flows_proto.ArtifactCollectorContext{
SessionId: self.flow_id,
ClientId: self.client_id,
@@ -677,7 +676,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFile() {
assert.Equal(self.T(), msg.FileBuffer.StoredSize, uint64(12))
}
- ArtifactCollectorProcessOneMessage(self.ConfigObj,
+ ArtifactCollectorProcessOneMessage(self.Ctx, self.ConfigObj,
collection_context, msg)
}
@@ -737,7 +736,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFile() {
// Check the System.Upload.Completion event.
artifact_path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj, self.client_id, self.flow_id,
+ self.Ctx, self.ConfigObj, self.client_id, self.flow_id,
"System.Upload.Completion")
assert.NoError(self.T(), err)
@@ -796,7 +795,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFileNTFS() {
nilTime, nilTime, nilTime, nilTime, fd)
// Get a new collection context.
- collection_context := NewCollectionContext(self.ConfigObj)
+ collection_context := NewCollectionContext(self.Ctx, self.ConfigObj)
collection_context.ArtifactCollectorContext = flows_proto.ArtifactCollectorContext{
SessionId: self.flow_id,
ClientId: self.client_id,
@@ -806,7 +805,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFileNTFS() {
// Process it.
for _, resp := range resp.Drain.WaitForStatsMessage(self.T()) {
resp.Source = self.client_id
- ArtifactCollectorProcessOneMessage(self.ConfigObj,
+ ArtifactCollectorProcessOneMessage(self.Ctx, self.ConfigObj,
collection_context, resp)
}
@@ -866,7 +865,7 @@ func (self *TestSuite) TestClientUploaderStoreSparseFileNTFS() {
// Check the System.Upload.Completion event.
artifact_path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj, self.client_id, self.flow_id,
+ self.Ctx, self.ConfigObj, self.client_id, self.flow_id,
"System.Upload.Completion")
assert.NoError(self.T(), err)
diff --git a/flows/client_flow_runner.go b/flows/client_flow_runner.go
index 6096414c8d1..08bccdf3ec8 100644
--- a/flows/client_flow_runner.go
+++ b/flows/client_flow_runner.go
@@ -67,7 +67,7 @@ func (self *ClientFlowRunner) ProcessMonitoringMessage(
client_id := msg.Source
if msg.VQLResponse != nil && msg.VQLResponse.Query != nil {
- err := self.MonitoringVQLResponse(client_id, flow_id, msg.VQLResponse)
+ err := self.MonitoringVQLResponse(ctx, client_id, flow_id, msg.VQLResponse)
if err != nil {
return fmt.Errorf("MonitoringVQLResponse: %w", err)
}
@@ -75,7 +75,7 @@ func (self *ClientFlowRunner) ProcessMonitoringMessage(
}
if msg.LogMessage != nil {
- err := self.MonitoringLogMessage(client_id, flow_id, msg.LogMessage)
+ err := self.MonitoringLogMessage(ctx, client_id, flow_id, msg.LogMessage)
if err != nil {
return fmt.Errorf("MonitoringLogMessage: %w", err)
}
@@ -83,7 +83,7 @@ func (self *ClientFlowRunner) ProcessMonitoringMessage(
}
if msg.FileBuffer != nil {
- err := self.FileBuffer(client_id, flow_id, msg.FileBuffer)
+ err := self.FileBuffer(ctx, client_id, flow_id, msg.FileBuffer)
if err != nil {
return fmt.Errorf("FileBuffer: %w", err)
}
@@ -94,7 +94,7 @@ func (self *ClientFlowRunner) ProcessMonitoringMessage(
}
func (self *ClientFlowRunner) MonitoringLogMessage(
- client_id, flow_id string,
+ ctx context.Context, client_id, flow_id string,
response *crypto_proto.LogMessage) error {
artifact_name := artifacts.DeobfuscateString(
@@ -108,7 +108,7 @@ func (self *ClientFlowRunner) MonitoringLogMessage(
return nil
}
- log_path_manager, err := artifact_paths.NewArtifactLogPathManager(
+ log_path_manager, err := artifact_paths.NewArtifactLogPathManager(ctx,
self.config_obj, client_id, flow_id, artifact_name)
if err != nil {
return err
@@ -133,7 +133,7 @@ func (self *ClientFlowRunner) MonitoringLogMessage(
}
func (self *ClientFlowRunner) MonitoringVQLResponse(
- client_id, flow_id string,
+ ctx context.Context, client_id, flow_id string,
response *actions_proto.VQLResponse) error {
// Ignore empty responses
@@ -158,7 +158,7 @@ func (self *ClientFlowRunner) MonitoringVQLResponse(
return err
}
- return journal.PushJsonlToArtifact(
+ return journal.PushJsonlToArtifact(ctx,
self.config_obj,
[]byte(response.JSONLResponse), int(response.TotalRows),
query_name, client_id, flow_id)
@@ -189,7 +189,7 @@ func (self *ClientFlowRunner) ProcessSingleMessage(
}
if msg.VQLResponse != nil {
- err := self.VQLResponse(client_id, flow_id, msg.VQLResponse)
+ err := self.VQLResponse(ctx, client_id, flow_id, msg.VQLResponse)
if err != nil {
return fmt.Errorf("VQLResponse: %w", err)
}
@@ -197,7 +197,7 @@ func (self *ClientFlowRunner) ProcessSingleMessage(
}
if msg.FlowStats != nil {
- err := self.FlowStats(client_id, flow_id, msg.FlowStats)
+ err := self.FlowStats(ctx, client_id, flow_id, msg.FlowStats)
if err != nil {
return fmt.Errorf("FlowStats: %w", err)
}
@@ -205,7 +205,7 @@ func (self *ClientFlowRunner) ProcessSingleMessage(
}
if msg.FileBuffer != nil {
- err := self.FileBuffer(client_id, flow_id, msg.FileBuffer)
+ err := self.FileBuffer(ctx, client_id, flow_id, msg.FileBuffer)
if err != nil {
return fmt.Errorf("FileBuffer: %w", err)
}
@@ -216,7 +216,7 @@ func (self *ClientFlowRunner) ProcessSingleMessage(
}
func (self *ClientFlowRunner) FileBuffer(
- client_id, flow_id string,
+ ctx context.Context, client_id, flow_id string,
file_buffer *actions_proto.FileBuffer) error {
if file_buffer == nil || file_buffer.Pathspec == nil {
@@ -328,7 +328,7 @@ func (self *ClientFlowRunner) FileBuffer(
return err
}
- return journal.PushRowsToArtifact(self.config_obj,
+ return journal.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{row},
"System.Upload.Completion",
client_id, flow_id)
@@ -341,7 +341,7 @@ func (self *ClientFlowRunner) Close(ctx context.Context) {
}
func (self *ClientFlowRunner) FlowStats(
- client_id, flow_id string,
+ ctx context.Context, client_id, flow_id string,
msg *crypto_proto.FlowStats) error {
// Write a partial ArtifactCollectorContext protobuf containing
@@ -394,7 +394,7 @@ func (self *ClientFlowRunner) FlowStats(
journal, err := services.GetJournal(self.config_obj)
if err == nil {
- journal.PushRowsToArtifactAsync(
+ journal.PushRowsToArtifactAsync(ctx,
self.config_obj, row, "System.Flow.Completion")
}
}
@@ -403,7 +403,7 @@ func (self *ClientFlowRunner) FlowStats(
}
func (self *ClientFlowRunner) VQLResponse(
- client_id, flow_id string,
+ ctx context.Context, client_id, flow_id string,
response *actions_proto.VQLResponse) error {
if response == nil || response.Query == nil || response.Query.Name == "" {
@@ -420,7 +420,7 @@ func (self *ClientFlowRunner) VQLResponse(
return nil
}
- path_manager, err := artifact_paths.NewArtifactPathManager(
+ path_manager, err := artifact_paths.NewArtifactPathManager(ctx,
self.config_obj, client_id, flow_id, response.Query.Name)
if err != nil {
return err
diff --git a/flows/housekeeping.go b/flows/housekeeping.go
index b2887ac0e35..7630496fc5f 100644
--- a/flows/housekeeping.go
+++ b/flows/housekeeping.go
@@ -143,7 +143,7 @@ func CheckClientStatus(
latest_timestamp := uint64(0)
for _, hunt := range hunts {
// Notify the hunt manager that we need to hunt this client.
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("HuntId", hunt.HuntId).
Set("ClientId", client_id),
diff --git a/flows/logs.go b/flows/logs.go
index 53c3f60d70b..9112c25d232 100644
--- a/flows/logs.go
+++ b/flows/logs.go
@@ -5,6 +5,7 @@
package flows
import (
+ "context"
"regexp"
"strings"
"sync"
@@ -121,13 +122,13 @@ func writeLogMessages(
// Flush the logs to disk. During execution the flow collects the logs
// in memory and then flushes it all when done.
func flushContextLogs(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext,
completion *utils.Completer) error {
// Handle monitoring flow specially.
if collection_context.SessionId == constants.MONITORING_WELL_KNOWN_FLOW {
- return flushContextLogsMonitoring(config_obj, collection_context)
+ return flushContextLogsMonitoring(ctx, config_obj, collection_context)
}
flow_path_manager := paths.NewFlowPathManager(
diff --git a/flows/monitoring.go b/flows/monitoring.go
index da029d6faf2..9e4c4cc72fa 100644
--- a/flows/monitoring.go
+++ b/flows/monitoring.go
@@ -6,6 +6,7 @@ package flows
import (
"bytes"
+ "context"
"github.com/Velocidex/ordereddict"
"github.com/prometheus/client_golang/prometheus"
@@ -36,7 +37,7 @@ type jsonBatch struct {
// Receive monitoring messages from the client.
func MonitoringProcessMessage(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext,
message *crypto_proto.VeloMessage) error {
@@ -48,7 +49,7 @@ func MonitoringProcessMessage(
switch message.RequestId {
case constants.TransferWellKnownFlowId:
- return appendUploadDataToFile(
+ return appendUploadDataToFile(ctx,
config_obj, collection_context, message)
}
@@ -81,7 +82,7 @@ func MonitoringProcessMessage(
// Logs from monitoring flow need to be handled especially since they
// are written with a time index.
func flushContextLogsMonitoring(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext) error {
// A single packet may have multiple log messages from
@@ -100,7 +101,7 @@ func flushContextLogsMonitoring(
// Try to get the writer from the cache.
rs_writer, pres := writers[artifact_name]
if !pres {
- log_path_manager, err := artifact_paths.NewArtifactLogPathManager(
+ log_path_manager, err := artifact_paths.NewArtifactLogPathManager(ctx,
config_obj, collection_context.ClientId,
collection_context.SessionId, artifact_name)
if err != nil {
@@ -142,7 +143,7 @@ func (self *CollectionContext) batchRows(
}
func flushMonitoringLogs(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
collection_context *CollectionContext) error {
journal, err := services.GetJournal(config_obj)
@@ -152,6 +153,7 @@ func flushMonitoringLogs(
for query_name, jsonl_buff := range collection_context.monitoring_batch {
err := journal.PushJsonlToArtifact(
+ ctx,
config_obj,
jsonl_buff.Bytes(), jsonl_buff.row_count,
query_name,
diff --git a/gui/velociraptor/src/components/artifacts/artifacts.jsx b/gui/velociraptor/src/components/artifacts/artifacts.jsx
index 5a8e56b9c21..78dc0635136 100644
--- a/gui/velociraptor/src/components/artifacts/artifacts.jsx
+++ b/gui/velociraptor/src/components/artifacts/artifacts.jsx
@@ -72,6 +72,8 @@ class ArtifactInspector extends React.Component {
showDeleteArtifactDialog: false,
showArtifactsUploadDialog: false,
current_filter: "",
+
+ version: 0,
}
componentDidMount = () => {
@@ -142,13 +144,20 @@ class ArtifactInspector extends React.Component {
e.preventDefault();
e.stopPropagation();
+ return this.getArtifactDescription(row.name);
+ }
+
+ getArtifactDescription = (name) => {
// Fetch the full description
api.post("v1/GetArtifacts", {
- names: [row.name],
+ names: [name],
}, this.source.token).then(response=>{
let items = response.data.items;
if (items.length > 0) {
- this.setState({fullSelectedDescriptor: items[0]});
+ this.setState({
+ fullSelectedDescriptor: items[0],
+ version: this.state.version+1,
+ });
};
});
return false;
@@ -235,6 +244,7 @@ class ArtifactInspector extends React.Component {
// Re-apply the search in case the user updated
// an artifact that should show up.
this.fetchRows(this.state.current_filter);
+ this.getArtifactDescription(selected);
this.setState({showEditedArtifactDialog: false});
}}
/>
@@ -341,6 +351,7 @@ class ArtifactInspector extends React.Component {
{ this.state.selectedDescriptor ?
:
diff --git a/gui/velociraptor/src/components/artifacts/reporting.jsx b/gui/velociraptor/src/components/artifacts/reporting.jsx
index 78a6e755155..9d242fd0c60 100644
--- a/gui/velociraptor/src/components/artifacts/reporting.jsx
+++ b/gui/velociraptor/src/components/artifacts/reporting.jsx
@@ -40,6 +40,7 @@ export default class VeloReportViewer extends React.Component {
data: {},
messages: [],
loading: true,
+ version: 0,
}
componentDidMount() {
@@ -110,8 +111,8 @@ export default class VeloReportViewer extends React.Component {
messages: response.data.messages || [],
data: JSON.parse(response.data.data),
loading: false,
+ version: this.state.version += 1,
};
-
for (var i=0; i
+
);
};
diff --git a/gui/velociraptor/src/components/tools/tool-viewer.jsx b/gui/velociraptor/src/components/tools/tool-viewer.jsx
index f4fd4c92f11..5ca876a14bc 100644
--- a/gui/velociraptor/src/components/tools/tool-viewer.jsx
+++ b/gui/velociraptor/src/components/tools/tool-viewer.jsx
@@ -12,14 +12,65 @@ import CardDeck from 'react-bootstrap/CardDeck';
import Form from 'react-bootstrap/Form';
import InputGroup from 'react-bootstrap/InputGroup';
import T from '../i8n/i8n.jsx';
+import Select from 'react-select';
+import VeloValueRenderer from '../utils/value.jsx';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classNames from "classnames";
+class ResetToolDialog extends React.Component {
+ static propTypes = {
+ tool: PropTypes.object,
+ onClose: PropTypes.func.isRequired,
+ };
+
+ componentDidMount = () => {
+ this.source = axios.CancelToken.source();
+ }
+
+ componentWillUnmount() {
+ this.source.cancel("unmounted");
+ }
+
+ setToolInfo = (tool) => {
+ api.post("v1/SetToolInfo", tool,
+ this.source.token).then((response) => {
+ this.setState({tool: response.data});
+ }).finally(() => {
+ this.props.onClose();
+ });
+ };
+
+ render() {
+ return
+
+ {T("Tool")} {
+ this.props.tool && this.props.tool.name}
+
+
+ {T("Confirm tool definition reset")}
+ {T("This will reset the tool to its original definition")}
+
+
+
+
+
+ ;
+ }
+}
+
export default class ToolViewer extends React.Component {
static propTypes = {
name: PropTypes.string,
+ version: PropTypes.number,
};
componentDidMount = () => {
@@ -32,17 +83,18 @@ export default class ToolViewer extends React.Component {
}
componentDidUpdate = (prevProps, prevState, rootNode) => {
- if (this.props.name !== prevProps.name) {
+ if (this.props.name !== prevProps.name ||
+ this.props.version !== prevProps.version) {
this.fetchToolInfo();
}
}
- fetchToolInfo = () => {
+ fetchToolInfo = (onclose) => {
api.get("v1/GetToolInfo",
{name: this.props.name},
this.source.token).then((response) => {
this.setState({tool: response.data});
- });
+ }).then(onclose);
}
state = {
@@ -276,8 +328,21 @@ export default class ToolViewer extends React.Component {
);
}
+ let tool_version_options = _.map(tool.versions, x=>{
+ return {value: x.artifact,
+ tool: x,
+ label: x.artifact,
+ isFixed: true};
+ });
return (
<>
+ { this.state.showUpdateDialog &&
+ this.fetchToolInfo(
+ x=>this.setState({showUpdateDialog: false}))}>
+
+ }
+ { tool.versions &&
+ <>
+ - {T("Other Definitions")}
+ -
+
+ >}
+ { tool.artifact &&
+ <>
+ - {T("Artifact Definition")}
+ - {tool.artifact}
>}
+
{ tool.name &&
<>
- {T("Tool Name")}
diff --git a/gui/velociraptor/src/components/widgets/preview_uploads.jsx b/gui/velociraptor/src/components/widgets/preview_uploads.jsx
index 59d36f97b36..94f426e7588 100644
--- a/gui/velociraptor/src/components/widgets/preview_uploads.jsx
+++ b/gui/velociraptor/src/components/widgets/preview_uploads.jsx
@@ -312,7 +312,7 @@ export default class PreviewUpload extends Component {
fs_components: normalizeComponentList(
components, client_id, flow_id, accessor),
client_id: client_id,
- org_id: window.globals.org_id || "root",
+ org_id: window.globals.OrgId || "root",
};
let url = 'v1/DownloadVFSFile';
diff --git a/paths/artifacts/logs.go b/paths/artifacts/logs.go
index b41c61f011a..c082a1832b6 100644
--- a/paths/artifacts/logs.go
+++ b/paths/artifacts/logs.go
@@ -122,11 +122,11 @@ func (self *ArtifactLogPathManager) GetAvailableFiles(
}
func NewArtifactLogPathManager(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
client_id, flow_id, full_artifact_name string) (
*ArtifactLogPathManager, error) {
- path_manager, err := NewArtifactPathManager(config_obj,
+ path_manager, err := NewArtifactPathManager(ctx, config_obj,
client_id, flow_id, full_artifact_name)
if err != nil {
return nil, err
diff --git a/paths/artifacts/paths.go b/paths/artifacts/paths.go
index b80f90706a8..164c677d26a 100644
--- a/paths/artifacts/paths.go
+++ b/paths/artifacts/paths.go
@@ -49,12 +49,12 @@ func NewArtifactPathManagerWithMode(
}
func NewArtifactPathManager(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
client_id, flow_id, full_artifact_name string) (
*ArtifactPathManager, error) {
artifact_name, artifact_source := paths.SplitFullSourceName(full_artifact_name)
- mode, err := GetArtifactMode(config_obj, artifact_name)
+ mode, err := GetArtifactMode(ctx, config_obj, artifact_name)
if err != nil {
return nil, err
}
@@ -304,7 +304,9 @@ func DayNameToTimestamp(name string) time.Time {
return time.Time{}
}
-func GetArtifactMode(config_obj *config_proto.Config, artifact_name string) (int, error) {
+func GetArtifactMode(
+ ctx context.Context, config_obj *config_proto.Config,
+ artifact_name string) (int, error) {
manager, err := services.GetRepositoryManager(config_obj)
if err != nil {
return 0, err
@@ -315,7 +317,8 @@ func GetArtifactMode(config_obj *config_proto.Config, artifact_name string) (int
return 0, err
}
- artifact_type, err := repository.GetArtifactType(config_obj, artifact_name)
+ artifact_type, err := repository.GetArtifactType(
+ ctx, config_obj, artifact_name)
if err != nil {
return 0, err
}
diff --git a/paths/artifacts/paths_test.go b/paths/artifacts/paths_test.go
index 2ca8343c171..ff16d2bfa90 100644
--- a/paths/artifacts/paths_test.go
+++ b/paths/artifacts/paths_test.go
@@ -97,7 +97,7 @@ func (self *PathManageTestSuite) TestPathManager() {
for _, testcase := range path_tests {
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
testcase.client_id,
testcase.flow_id,
testcase.full_artifact_name)
diff --git a/reporting/expand.go b/reporting/expand.go
index 875671f8057..dfa2da381c3 100644
--- a/reporting/expand.go
+++ b/reporting/expand.go
@@ -64,6 +64,7 @@ type Expansions struct {
// Support a number of expansions in description strings.
func FormatDescription(
+ ctx context.Context,
config_obj *config_proto.Config,
description string,
rows []vfilter.Row) string {
@@ -92,7 +93,8 @@ func FormatDescription(
return buffer.String()
}
-func (self *Expansions) DocFrom(artifact string) string {
+func (self *Expansions) DocFrom(
+ ctx context.Context, artifact string) string {
manager, err := services.GetRepositoryManager(self.config_obj)
if err != nil {
return ""
@@ -103,7 +105,7 @@ func (self *Expansions) DocFrom(artifact string) string {
return ""
}
- artifact_definition, pres := repository.Get(self.config_obj, artifact)
+ artifact_definition, pres := repository.Get(ctx, self.config_obj, artifact)
if !pres {
return ""
}
diff --git a/reporting/gui.go b/reporting/gui.go
index f02b7c47aa5..c941d026343 100644
--- a/reporting/gui.go
+++ b/reporting/gui.go
@@ -166,7 +166,7 @@ func (self *GuiTemplateEngine) Expand(values ...interface{}) interface{} {
}
func (self *GuiTemplateEngine) Import(artifact, name string) interface{} {
- definition, pres := self.BaseTemplateEngine.Repository.Get(
+ definition, pres := self.BaseTemplateEngine.Repository.Get(self.ctx,
self.config_obj, artifact)
if !pres {
self.Error("Unknown artifact %v", artifact)
@@ -591,7 +591,8 @@ func NewGuiTemplateEngine(
}
base_engine, err := newBaseTemplateEngine(
- config_obj, scope, acl_manager, uploader, repository, artifact_name)
+ ctx, config_obj, scope, acl_manager,
+ uploader, repository, artifact_name)
if err != nil {
return nil, err
}
diff --git a/reporting/html.go b/reporting/html.go
index 3a3d9bfbaa3..b1dffe5f05f 100644
--- a/reporting/html.go
+++ b/reporting/html.go
@@ -218,7 +218,7 @@ func (self *HTMLTemplateEngine) getMultiLineQuery(query string) (string, error)
}
func (self *HTMLTemplateEngine) Import(artifact, name string) interface{} {
- definition, pres := self.BaseTemplateEngine.Repository.Get(
+ definition, pres := self.BaseTemplateEngine.Repository.Get(self.ctx,
self.config_obj, artifact)
if !pres {
self.Error("Unknown artifact %v", artifact)
@@ -332,7 +332,7 @@ func NewHTMLTemplateEngine(
sanitize_html bool) (
*HTMLTemplateEngine, error) {
- base_engine, err := newBaseTemplateEngine(
+ base_engine, err := newBaseTemplateEngine(ctx,
config_obj, scope, acl_manager, nil, repository,
artifact_name)
if err != nil {
diff --git a/reporting/report.go b/reporting/report.go
index 4adc360f84d..46062b89742 100644
--- a/reporting/report.go
+++ b/reporting/report.go
@@ -1,6 +1,7 @@
package reporting
import (
+ "context"
"fmt"
"regexp"
"strings"
@@ -152,6 +153,7 @@ func GenerateMonitoringDailyReport(template_engine TemplateEngine,
}
func GenerateArtifactDescriptionReport(
+ ctx context.Context,
template_engine TemplateEngine,
config_obj *config_proto.Config) (
string, error) {
@@ -167,7 +169,7 @@ func GenerateArtifactDescriptionReport(
return "", err
}
- template_artifact, pres := repository.Get(
+ template_artifact, pres := repository.Get(ctx,
config_obj, "Server.Internal.ArtifactDescription")
if pres {
template_engine.SetEnv("artifact", artifact)
@@ -319,6 +321,7 @@ func GenerateHuntReport(template_engine TemplateEngine,
}
func newBaseTemplateEngine(
+ ctx context.Context,
config_obj *config_proto.Config,
scope vfilter.Scope,
acl_manager vql_subsystem.ACLManager,
@@ -327,7 +330,7 @@ func newBaseTemplateEngine(
artifact_name string) (
*BaseTemplateEngine, error) {
- artifact, pres := repository.Get(config_obj, artifact_name)
+ artifact, pres := repository.Get(ctx, config_obj, artifact_name)
if !pres {
return nil, fmt.Errorf(
"Artifact %v not known.", artifact_name)
diff --git a/reporting/text_expander.go b/reporting/text_expander.go
index 357a7e7c65e..57b41fbfd64 100644
--- a/reporting/text_expander.go
+++ b/reporting/text_expander.go
@@ -120,12 +120,13 @@ func (self *TextTemplateEngine) Table(values ...interface{}) string {
}
func NewTextTemplateEngine(
+ ctx context.Context,
config_obj *config_proto.Config,
scope vfilter.Scope,
acl_manager vql_subsystem.ACLManager,
repository services.Repository,
artifact_name string) (*TextTemplateEngine, error) {
- base_engine, err := newBaseTemplateEngine(
+ base_engine, err := newBaseTemplateEngine(ctx,
config_obj, scope, acl_manager, nil, repository, artifact_name)
if err != nil {
return nil, err
diff --git a/result_sets/simple/simple_test.go b/result_sets/simple/simple_test.go
index 4a2ff5e173a..c89407fb798 100644
--- a/result_sets/simple/simple_test.go
+++ b/result_sets/simple/simple_test.go
@@ -53,7 +53,7 @@ func (self *ResultSetTestSuite) SetupTest() {
func (self *ResultSetTestSuite) TestResultSetSimple() {
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
self.client_id,
self.flow_id,
"Generic.Client.Info/BasicInformation")
diff --git a/result_sets/timed/reader_test.go b/result_sets/timed/reader_test.go
index eb7feb0d055..cd05ee5ecd0 100644
--- a/result_sets/timed/reader_test.go
+++ b/result_sets/timed/reader_test.go
@@ -20,7 +20,7 @@ func (self *TimedResultSetTestSuite) TestTimedResultSetMigration() {
// Start off by writing some events on a queue.
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
self.client_id,
self.flow_id,
"Windows.Events.ProcessCreation")
diff --git a/result_sets/timed/writer_test.go b/result_sets/timed/writer_test.go
index 519f5af7dcf..4940d9692fe 100644
--- a/result_sets/timed/writer_test.go
+++ b/result_sets/timed/writer_test.go
@@ -81,7 +81,7 @@ func (self *TimedResultSetTestSuite) TestTimedResultSetWriting() {
// Start off by writing some events on a queue.
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
self.client_id,
self.flow_id,
"Windows.Events.ProcessCreation")
@@ -158,7 +158,7 @@ func (self *TimedResultSetTestSuite) TestTimedResultSetWritingJsonl() {
// Start off by writing some events on a queue.
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
self.client_id,
self.flow_id,
"Windows.Events.ProcessCreation")
@@ -237,7 +237,7 @@ func (self *TimedResultSetTestSuite) TestTimedResultSetWritingNoFlushing() {
// Start off by writing some events on a queue.
path_manager, err := artifacts.NewArtifactPathManager(
- self.ConfigObj,
+ self.Ctx, self.ConfigObj,
self.client_id,
self.flow_id,
"Windows.Events.ProcessCreation")
diff --git a/server/comms.go b/server/comms.go
index cabd1281a3a..67539f08097 100644
--- a/server/comms.go
+++ b/server/comms.go
@@ -538,7 +538,7 @@ func send_client_messages(server_obj *Server) http.Handler {
}
// This should trigger an enrollment flow.
- err = journal.PushRowsToArtifact(org_config_obj,
+ err = journal.PushRowsToArtifact(ctx, org_config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("ClientId", source)},
@@ -564,7 +564,7 @@ func send_client_messages(server_obj *Server) http.Handler {
// Send a message that there is a client conflict.
journal, err := services.GetJournal(org_config_obj)
if err == nil {
- journal.PushRowsToArtifactAsync(org_config_obj,
+ journal.PushRowsToArtifactAsync(ctx, org_config_obj,
ordereddict.NewDict().Set("ClientId", source),
"Server.Internal.ClientConflict")
}
diff --git a/server/enroll.go b/server/enroll.go
index fb8fe19abd6..d4e17001ac5 100644
--- a/server/enroll.go
+++ b/server/enroll.go
@@ -49,7 +49,7 @@ func enroll(
return err
}
- return journal.PushRowsToArtifact(config_obj,
+ return journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("ClientId", client_id)},
diff --git a/server/server_test.go b/server/server_test.go
index 68e3e12d5c8..04ca7fb322c 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -305,7 +305,7 @@ func (self *ServerTestSuite) TestMonitoring() {
})
runner.Close(context.Background())
- path_manager, err := artifacts.NewArtifactPathManager(self.ConfigObj,
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx, self.ConfigObj,
self.client_id, constants.MONITORING_WELL_KNOWN_FLOW,
"Generic.Client.Stats")
assert.NoError(self.T(), err)
@@ -512,7 +512,8 @@ func (self *ServerTestSuite) TestVQLResponse() {
})
runner.Close(context.Background())
- flow_path_manager, err := artifacts.NewArtifactPathManager(self.ConfigObj,
+ flow_path_manager, err := artifacts.NewArtifactPathManager(
+ self.Ctx, self.ConfigObj,
self.client_id, flow_id, "Generic.Client.Info")
assert.NoError(self.T(), err)
diff --git a/services/client_info/client_info.go b/services/client_info/client_info.go
index 0f57280439c..f4594172717 100644
--- a/services/client_info/client_info.go
+++ b/services/client_info/client_info.go
@@ -389,7 +389,7 @@ func (self *ClientInfoManager) MutationSync(
// Update the ping info to the latest
//self.UpdateMostRecentPing()
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("Mutation", self.mutation_manager.GetMutation()).
Set("From", self.uuid),
diff --git a/services/client_info/tasks.go b/services/client_info/tasks.go
index 9b172d4fc72..d6dea297f2e 100644
--- a/services/client_info/tasks.go
+++ b/services/client_info/tasks.go
@@ -114,7 +114,7 @@ func (self *ClientInfoManager) QueueMessagesForClient(
// When the completer is done send a message to all the minions
// that the tasks are ready to be read.
completer := utils.NewCompleter(func() {
- journal.PushRowsToArtifactAsync(self.config_obj,
+ journal.PushRowsToArtifactAsync(ctx, self.config_obj,
ordereddict.NewDict().
Set("ClientId", client_id).
Set("Notify", notify),
@@ -171,7 +171,7 @@ func (self *ClientInfoManager) QueueMessageForClient(
completion()
}
- journal.PushRowsToArtifactAsync(self.config_obj,
+ journal.PushRowsToArtifactAsync(ctx, self.config_obj,
ordereddict.NewDict().
Set("ClientId", client_id).
Set("Notify", notify),
diff --git a/services/client_monitoring/client_monitoring.go b/services/client_monitoring/client_monitoring.go
index 767d6f21d79..b759e53a26f 100644
--- a/services/client_monitoring/client_monitoring.go
+++ b/services/client_monitoring/client_monitoring.go
@@ -259,7 +259,7 @@ func (self *ClientEventTable) setClientMonitoringState(
})
}
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("setter", self.id).
diff --git a/services/client_monitoring/client_monitoring_test.go b/services/client_monitoring/client_monitoring_test.go
index e157a56730a..a7ed6d159b1 100644
--- a/services/client_monitoring/client_monitoring_test.go
+++ b/services/client_monitoring/client_monitoring_test.go
@@ -118,7 +118,9 @@ func (self *ClientMonitoringTestSuite) TestUpdatingArtifacts() {
repository_manager, err := services.GetRepositoryManager(self.ConfigObj)
assert.NoError(self.T(), err)
- _, err = repository_manager.SetArtifactFile(self.ConfigObj, "", `
+ ctx := self.Ctx
+ _, err = repository_manager.SetArtifactFile(ctx,
+ self.ConfigObj, "", `
name: TestArtifact
sources:
- query:
@@ -147,7 +149,8 @@ sources:
table_version = new_table_message.UpdateEventTable.Version
// Now delete the artifact completely
- repository_manager.DeleteArtifactFile(self.ConfigObj, "", "TestArtifact")
+ repository_manager.DeleteArtifactFile(
+ ctx, self.ConfigObj, "", "TestArtifact")
// The table should magically be updated!
table_json := ""
@@ -173,7 +176,7 @@ func (self *ClientMonitoringTestSuite) TestUpdatingClientTable() {
current_clock := &utils.IncClock{NowTime: 10}
repository_manager, _ := services.GetRepositoryManager(self.ConfigObj)
- repository_manager.SetArtifactFile(self.ConfigObj, "", `
+ repository_manager.SetArtifactFile(self.Ctx, self.ConfigObj, "", `
name: TestArtifact
sources:
- query:
@@ -222,7 +225,7 @@ func (self *ClientMonitoringTestSuite) TestUpdatingClientTableMultiFrontend() {
current_clock := &utils.IncClock{NowTime: 10}
repository_manager, _ := services.GetRepositoryManager(self.ConfigObj)
- repository_manager.SetArtifactFile(self.ConfigObj, "", `
+ repository_manager.SetArtifactFile(self.Ctx, self.ConfigObj, "", `
name: TestArtifact
sources:
- query:
diff --git a/services/client_monitoring/events.go b/services/client_monitoring/events.go
index 9632d781f28..67629f3b7b8 100644
--- a/services/client_monitoring/events.go
+++ b/services/client_monitoring/events.go
@@ -21,7 +21,7 @@ func (self *ClientEventTable) ListAvailableEventResults(
*api_proto.ListAvailableEventResultsResponse, error) {
if in.Artifact == "" {
- return listAvailableEventArtifacts(self.config_obj, in)
+ return listAvailableEventArtifacts(ctx, self.config_obj, in)
}
return listAvailableEventTimestamps(ctx, self.config_obj, in)
}
@@ -32,7 +32,7 @@ func listAvailableEventTimestamps(
in *api_proto.ListAvailableEventResultsRequest) (
*api_proto.ListAvailableEventResultsResponse, error) {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, in.ClientId, "", in.Artifact)
if err != nil {
return nil, err
@@ -76,7 +76,7 @@ func listAvailableEventTimestampFiles(
}
func listAvailableEventArtifacts(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
in *api_proto.ListAvailableEventResultsRequest) (
*api_proto.ListAvailableEventResultsResponse, error) {
@@ -87,7 +87,7 @@ func listAvailableEventArtifacts(
exemplar = "Server.Monitor.Health"
}
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, in.ClientId, "", exemplar)
if err != nil {
return nil, err
@@ -96,12 +96,13 @@ func listAvailableEventArtifacts(
// getAllArtifacts analyses the path name from disk and adds
// to the events list.
seen := make(map[string]*api_proto.AvailableEvent)
- err = getAllArtifacts(config_obj, path_manager.GetRootPath(), seen)
+ err = getAllArtifacts(ctx, config_obj, path_manager.GetRootPath(), seen)
if err != nil {
return nil, err
}
- err = getAllArtifacts(config_obj, path_manager.Logs().GetRootPath(), seen)
+ err = getAllArtifacts(ctx, config_obj,
+ path_manager.Logs().GetRootPath(), seen)
if err != nil {
return nil, err
}
@@ -119,6 +120,7 @@ func listAvailableEventArtifacts(
}
func getAllArtifacts(
+ ctx context.Context,
config_obj *config_proto.Config,
log_path api.FSPathSpec,
seen map[string]*api_proto.AvailableEvent) error {
@@ -154,7 +156,7 @@ func getAllArtifacts(
// Check if this is a valid artifact.
artifact_base_name := relative_path[0]
- _, pres := repository.Get(config_obj, artifact_base_name)
+ _, pres := repository.Get(ctx, config_obj, artifact_base_name)
if !pres {
return nil
}
diff --git a/services/frontend/frontend.go b/services/frontend/frontend.go
index 63f16e8232c..a83e7cbb49f 100644
--- a/services/frontend/frontend.go
+++ b/services/frontend/frontend.go
@@ -68,7 +68,7 @@ func PushMetrics(ctx context.Context, wg *sync.WaitGroup,
rows[0] = ordereddict.NewDict().
Set("Node", node_name).
Set("Metrics", metrics.ToDict())
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
rows, "Server.Internal.FrontendMetrics",
"server", "")
}
@@ -300,7 +300,7 @@ func (self *MasterFrontendManager) UpdateStats(ctx context.Context) {
continue
}
- _ = journal.PushRowsToArtifact(org_config_obj,
+ _ = journal.PushRowsToArtifact(ctx, org_config_obj,
[]*ordereddict.Dict{v},
"Server.Monitor.Health/Prometheus", "server", "")
}
diff --git a/services/hunt_dispatcher.go b/services/hunt_dispatcher.go
index d6ccc1ca51d..75aec42304e 100644
--- a/services/hunt_dispatcher.go
+++ b/services/hunt_dispatcher.go
@@ -70,7 +70,7 @@ type IHuntDispatcher interface {
// Modify a hunt under lock. The hunt will be synchronized to
// all frontends. Return true to indicate the hunt was modified.
- ModifyHuntObject(hunt_id string,
+ ModifyHuntObject(ctx context.Context, hunt_id string,
cb func(hunt *api_proto.Hunt) HuntModificationAction,
) HuntModificationAction
@@ -83,9 +83,7 @@ type IHuntDispatcher interface {
// Gets read only access to the hunt object.
GetHunt(hunt_id string) (*api_proto.Hunt, bool)
- GetFlows(
- ctx context.Context,
- config_obj *config_proto.Config,
+ GetFlows(ctx context.Context, config_obj *config_proto.Config,
scope vfilter.Scope,
hunt_id string, start int) chan *api_proto.FlowDetails
@@ -99,7 +97,8 @@ type IHuntDispatcher interface {
in *api_proto.ListHuntsRequest) (*api_proto.ListHuntsResponse, error)
// Send a mutation to a hunt object.
- MutateHunt(config_obj *config_proto.Config,
+ MutateHunt(ctx context.Context,
+ config_obj *config_proto.Config,
mutation *api_proto.HuntMutation) error
// Re-read the hunts from the data store. This happens
diff --git a/services/hunt_dispatcher/hunt_dispatcher.go b/services/hunt_dispatcher/hunt_dispatcher.go
index 32996c811cc..3316496554a 100644
--- a/services/hunt_dispatcher/hunt_dispatcher.go
+++ b/services/hunt_dispatcher/hunt_dispatcher.go
@@ -136,7 +136,7 @@ func (self *HuntDispatcher) participateAllConnectedClients(
}
// Notify the hunt manager about the new client
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("HuntId", hunt_id).
Set("ClientId", c),
@@ -268,14 +268,14 @@ func (self *HuntDispatcher) GetHunt(hunt_id string) (*api_proto.Hunt, bool) {
// Therefore, writers may write mutations and expect they take an
// unspecified time to appear in the hunt details.
func (self *HuntDispatcher) MutateHunt(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
mutation *api_proto.HuntMutation) error {
journal, err := services.GetJournal(config_obj)
if err != nil {
return err
}
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("hunt_id", mutation.HuntId).
Set("mutation", mutation),
@@ -287,7 +287,7 @@ func (self *HuntDispatcher) MutateHunt(
// Modify the hunt object under lock and also inform all other
// dispatchers about the new state.
func (self *HuntDispatcher) ModifyHuntObject(
- hunt_id string,
+ ctx context.Context, hunt_id string,
cb func(hunt *api_proto.Hunt) services.HuntModificationAction) services.HuntModificationAction {
logger := logging.GetLogger(self.config_obj, &logging.FrontendComponent)
@@ -326,7 +326,7 @@ func (self *HuntDispatcher) ModifyHuntObject(
if err == nil {
// Make sure these are pushed out ASAP to the other
// dispatchers.
- journal.PushRowsToArtifact(self.config_obj,
+ journal.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("HuntId", hunt_id).
@@ -348,7 +348,7 @@ func (self *HuntDispatcher) ModifyHuntObject(
if err == nil {
// Make sure these are pushed out ASAP to the other
// dispatchers.
- journal.PushRowsToArtifact(self.config_obj,
+ journal.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("HuntId", hunt_id).
@@ -508,8 +508,7 @@ func (self *HuntDispatcher) CreateHunt(
hunt.Artifacts = hunt.StartRequest.Artifacts
hunt.ArtifactSources = []string{}
for _, artifact := range hunt.StartRequest.Artifacts {
- for _, source := range GetArtifactSources(
- config_obj, artifact) {
+ for _, source := range GetArtifactSources(ctx, config_obj, artifact) {
hunt.ArtifactSources = append(
hunt.ArtifactSources, path.Join(artifact, source))
}
@@ -568,7 +567,7 @@ func (self *HuntDispatcher) CreateHunt(
return "", err
}
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{row}, "System.Hunt.Creation",
"server", hunt.HuntId)
if err != nil {
diff --git a/services/hunt_dispatcher/hunt_dispatcher_test.go b/services/hunt_dispatcher/hunt_dispatcher_test.go
index c8bc1773f04..3d1b3334dcf 100644
--- a/services/hunt_dispatcher/hunt_dispatcher_test.go
+++ b/services/hunt_dispatcher/hunt_dispatcher_test.go
@@ -1,6 +1,7 @@
package hunt_dispatcher_test
import (
+ "context"
"fmt"
"sort"
"testing"
@@ -100,7 +101,8 @@ func (self *HuntDispatcherTestSuite) TestModifyingHuntFlushToDatastore() {
assert.NoError(self.T(), err)
// Modify a hunt and flush to datastore immediately
- modification := self.master_dispatcher.ModifyHuntObject("H.1",
+ ctx := context.Background()
+ modification := self.master_dispatcher.ModifyHuntObject(ctx, "H.1",
func(hunt *api_proto.Hunt) services.HuntModificationAction {
hunt.State = api_proto.Hunt_STOPPED
return services.HuntFlushToDatastore
@@ -138,7 +140,8 @@ func (self *HuntDispatcherTestSuite) TestModifyingHuntPropagateChanges() {
assert.Equal(self.T(), hunt_obj.State, api_proto.Hunt_RUNNING)
// Now modify a hunt with services.HuntPropagateChanges
- modification := self.master_dispatcher.ModifyHuntObject("H.2",
+ ctx := self.Ctx
+ modification := self.master_dispatcher.ModifyHuntObject(ctx, "H.2",
func(hunt *api_proto.Hunt) services.HuntModificationAction {
hunt.State = api_proto.Hunt_STOPPED
return services.HuntPropagateChanges
diff --git a/services/hunt_dispatcher/list.go b/services/hunt_dispatcher/list.go
index 7ae6ecf9d52..ab82d9618bc 100644
--- a/services/hunt_dispatcher/list.go
+++ b/services/hunt_dispatcher/list.go
@@ -17,7 +17,7 @@ import (
// Backwards compatibility: Figure out the list of collected hunts
// from the hunt object's request
func FindCollectedArtifacts(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
hunt *api_proto.Hunt) {
if hunt == nil || hunt.StartRequest == nil ||
hunt.StartRequest.Artifacts == nil {
@@ -32,8 +32,7 @@ func FindCollectedArtifacts(
hunt.Artifacts = hunt.StartRequest.Artifacts
hunt.ArtifactSources = []string{}
for _, artifact := range hunt.StartRequest.Artifacts {
- for _, source := range GetArtifactSources(
- config_obj, artifact) {
+ for _, source := range GetArtifactSources(ctx, config_obj, artifact) {
hunt.ArtifactSources = append(
hunt.ArtifactSources,
path.Join(artifact, source))
@@ -91,8 +90,9 @@ func (self *HuntDispatcher) ListHunts(
}, nil
}
-func GetHunt(config_obj *config_proto.Config, in *api_proto.GetHuntRequest) (
- hunt *api_proto.Hunt, err error) {
+func GetHunt(
+ ctx context.Context, config_obj *config_proto.Config,
+ in *api_proto.GetHuntRequest) (hunt *api_proto.Hunt, err error) {
var hunt_obj *api_proto.Hunt
@@ -107,7 +107,7 @@ func GetHunt(config_obj *config_proto.Config, in *api_proto.GetHuntRequest) (
}
// Normalize the hunt object
- FindCollectedArtifacts(config_obj, hunt_obj)
+ FindCollectedArtifacts(ctx, config_obj, hunt_obj)
if hunt_obj == nil || hunt_obj.Stats == nil {
return nil, errors.New("Not found")
diff --git a/services/hunt_dispatcher/modify.go b/services/hunt_dispatcher/modify.go
index e8d2da730f0..f96e1acc36a 100644
--- a/services/hunt_dispatcher/modify.go
+++ b/services/hunt_dispatcher/modify.go
@@ -48,7 +48,7 @@ func (self *HuntDispatcher) ModifyHunt(
return err
}
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{row}, "System.Hunt.Archive",
"server", hunt_modification.HuntId)
if err != nil {
@@ -76,5 +76,5 @@ func (self *HuntDispatcher) ModifyHunt(
mutation.State = api_proto.Hunt_STOPPED
}
- return self.MutateHunt(config_obj, mutation)
+ return self.MutateHunt(ctx, config_obj, mutation)
}
diff --git a/services/hunt_dispatcher/utils.go b/services/hunt_dispatcher/utils.go
index 6b87e389b50..9e1de1cb8fe 100644
--- a/services/hunt_dispatcher/utils.go
+++ b/services/hunt_dispatcher/utils.go
@@ -1,12 +1,14 @@
package hunt_dispatcher
import (
+ "context"
+
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
"www.velocidex.com/golang/velociraptor/services"
)
func GetArtifactSources(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
artifact string) []string {
result := []string{}
manager, err := services.GetRepositoryManager(config_obj)
@@ -16,7 +18,7 @@ func GetArtifactSources(
repository, err := manager.GetGlobalRepository(config_obj)
if err == nil {
- artifact_obj, pres := repository.Get(config_obj, artifact)
+ artifact_obj, pres := repository.Get(ctx, config_obj, artifact)
if pres {
for _, source := range artifact_obj.Sources {
result = append(result, source.Name)
diff --git a/services/hunt_manager/hunt_manager.go b/services/hunt_manager/hunt_manager.go
index ef695a6264a..56ff7e7e506 100644
--- a/services/hunt_manager/hunt_manager.go
+++ b/services/hunt_manager/hunt_manager.go
@@ -164,11 +164,11 @@ func (self *HuntManager) ProcessMutation(
return err
}
- return self.processMutation(config_obj, mutation)
+ return self.processMutation(ctx, config_obj, mutation)
}
func (self *HuntManager) processMutation(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
mutation *api_proto.HuntMutation) error {
dispatcher, err := services.GetHuntDispatcher(config_obj)
@@ -176,7 +176,7 @@ func (self *HuntManager) processMutation(
return err
}
- dispatcher.ModifyHuntObject(mutation.HuntId,
+ dispatcher.ModifyHuntObject(ctx, mutation.HuntId,
func(hunt_obj *api_proto.Hunt) services.HuntModificationAction {
modification := services.HuntUnmodified
@@ -393,7 +393,7 @@ func (self *HuntManager) ProcessFlowCompletion(
// status, so we dont bother broadcasting a mutation for them. We
// only need to update the local hunt dispatcher on the master
// node which will flush to disk eventually.
- err := self.processMutation(config_obj, mutation)
+ err := self.processMutation(ctx, config_obj, mutation)
if err != nil {
return err
}
@@ -461,7 +461,7 @@ func (self *HuntManager) participateInAllHunts(ctx context.Context,
return nil
}
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("HuntId", hunt.HuntId).
Set("ClientId", client_id), "System.Hunt.Participation")
@@ -555,7 +555,7 @@ func (self *HuntManager) ProcessParticipation(
now > hunt_obj.Expires {
// Hunt is expired, stop the hunt.
- return dispatcher.MutateHunt(config_obj,
+ return dispatcher.MutateHunt(ctx, config_obj,
&api_proto.HuntMutation{
HuntId: participation_row.HuntId,
Stats: &api_proto.HuntStats{Stopped: true}})
@@ -774,7 +774,7 @@ func scheduleHuntOnClient(
return err
}
- err = dispatcher.MutateHunt(config_obj,
+ err = dispatcher.MutateHunt(ctx, config_obj,
&api_proto.HuntMutation{
HuntId: hunt_id,
Stats: &api_proto.HuntStats{
diff --git a/services/hunt_manager/hunt_manager_test.go b/services/hunt_manager/hunt_manager_test.go
index 4b72f203bae..3afbac5e8e3 100644
--- a/services/hunt_manager/hunt_manager_test.go
+++ b/services/hunt_manager/hunt_manager_test.go
@@ -90,7 +90,7 @@ func (self *HuntTestSuite) TestHuntManager() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id),
@@ -152,7 +152,7 @@ func (self *HuntTestSuite) TestHuntWithLabelClientNoLabel() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id).
@@ -228,7 +228,7 @@ func (self *HuntTestSuite) TestHuntWithLabelClientHasLabelDifferentCase() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id).
@@ -284,7 +284,7 @@ func (self *HuntTestSuite) TestHuntWithOverride() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id).
@@ -354,7 +354,7 @@ func (self *HuntTestSuite) TestHuntWithLabelClientHasLabel() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id).
@@ -433,7 +433,7 @@ func (self *HuntTestSuite) TestHuntWithLabelClientHasExcludedLabel() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", self.hunt_id).
Set("ClientId", self.client_id).
@@ -501,7 +501,7 @@ func (self *HuntTestSuite) TestHuntClientOSCondition() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(t, err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("HuntId", self.hunt_id).
@@ -593,7 +593,7 @@ func (self *HuntTestSuite) TestHuntClientOSConditionInterrogation() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", self.client_id),
}, "Server.Internal.Interrogation", self.client_id, ""))
@@ -638,7 +638,8 @@ func (self *HuntTestSuite) TestHuntManagerMutations() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(
+ self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", hunt_obj.HuntId).
Set("ClientId", self.client_id),
@@ -665,7 +666,8 @@ func (self *HuntTestSuite) TestHuntManagerMutations() {
State: flows_proto.ArtifactCollectorContext_FINISHED,
}
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(
+ self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("Timestamp", time.Now().UTC().Unix()).
Set("Flow", flow_obj).
@@ -680,7 +682,7 @@ func (self *HuntTestSuite) TestHuntManagerMutations() {
// To stop the hunt, we send a hunt mutation that sets the
// state of the hunt to stopped.
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", hunt_obj.HuntId).
Set("mutation", &api_proto.HuntMutation{
@@ -725,7 +727,7 @@ func (self *HuntTestSuite) TestHuntManagerErrors() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", hunt_obj.HuntId).
Set("ClientId", self.client_id),
@@ -744,7 +746,7 @@ func (self *HuntTestSuite) TestHuntManagerErrors() {
State: flows_proto.ArtifactCollectorContext_ERROR,
}
- assert.NoError(self.T(), journal.PushRowsToArtifact(self.ConfigObj,
+ assert.NoError(self.T(), journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("Timestamp", time.Now().UTC().Unix()).
Set("Flow", flow_obj).
diff --git a/services/interrogation/interrogation.go b/services/interrogation/interrogation.go
index 90001505b16..933e34eabb6 100644
--- a/services/interrogation/interrogation.go
+++ b/services/interrogation/interrogation.go
@@ -135,7 +135,7 @@ func (self *EnrollmentService) ProcessEnrollment(
// Allow the user to override the basic interrogation
// functionality. Check for any customized versions
- definition, pres := repository.Get(config_obj, "Custom.Generic.Client.Info")
+ definition, pres := repository.Get(ctx, config_obj, "Custom.Generic.Client.Info")
if pres {
interrogation_artifact = definition.Name
}
@@ -157,7 +157,7 @@ func (self *EnrollmentService) ProcessEnrollment(
// Notify the client
notifier, err := services.GetNotifier(config_obj)
if err == nil {
- notifier.NotifyListener(
+ notifier.NotifyListener(ctx,
config_obj, client_id, "Interrogate")
}
})
@@ -205,7 +205,7 @@ func (self *EnrollmentService) ProcessInterrogateResults(
client_id, flow_id, artifact string) error {
file_store_factory := file_store.GetFileStore(config_obj)
- path_manager, err := artifacts.NewArtifactPathManager(config_obj,
+ path_manager, err := artifacts.NewArtifactPathManager(ctx, config_obj,
client_id, flow_id, artifact)
if err != nil {
return err
@@ -299,7 +299,7 @@ func (self *EnrollmentService) ProcessInterrogateResults(
func() {
client_info_manager.Flush(ctx, client_id)
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("ClientId", client_id),
"Server.Internal.Interrogation")
diff --git a/services/interrogation/interrogation_test.go b/services/interrogation/interrogation_test.go
index 1c0f3922cd0..0785e5caed9 100644
--- a/services/interrogation/interrogation_test.go
+++ b/services/interrogation/interrogation_test.go
@@ -52,11 +52,12 @@ func (self *ServicesTestSuite) EmulateCollection(
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- journal.PushRowsToArtifact(self.ConfigObj,
+ ctx := context.Background()
+ journal.PushRowsToArtifact(ctx, self.ConfigObj,
rows, artifact, self.client_id, self.flow_id)
// Emulate a flow completion message coming from the flow processor.
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", self.client_id).
Set("FlowId", self.flow_id).
@@ -99,7 +100,7 @@ func (self *ServicesTestSuite) TestInterrogationService() {
// Check the label is set on the client.
labeler := services.GetLabeler(self.ConfigObj)
- vtesting.WaitUntil(2*time.Second, self.T(), func() bool {
+ vtesting.WaitUntil(5*time.Second, self.T(), func() bool {
return labeler.IsLabelSet(
context.Background(), self.ConfigObj, self.client_id, "Foo")
})
@@ -132,7 +133,8 @@ func (self *ServicesTestSuite) TestEnrollService() {
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- err = journal.PushRowsToArtifact(self.ConfigObj,
+ ctx := self.Ctx
+ err = journal.PushRowsToArtifact(ctx, self.ConfigObj,
[]*ordereddict.Dict{
enroll_message, enroll_message, enroll_message, enroll_message,
},
diff --git a/services/inventory.go b/services/inventory.go
index b27cec55d43..91449019e2f 100644
--- a/services/inventory.go
+++ b/services/inventory.go
@@ -36,7 +36,8 @@ type Inventory interface {
Get() *artifacts_proto.ThirdParty
// Probe for a specific tool without materializing the tool.
- ProbeToolInfo(name string) (*artifacts_proto.Tool, error)
+ ProbeToolInfo(ctx context.Context, config_obj *config_proto.Config,
+ name string) (*artifacts_proto.Tool, error)
// Get information about a specific tool. If the tool is set
// to serve locally, the tool will be fetched from its
@@ -54,7 +55,7 @@ type Inventory interface {
// actually valid and available, they need to call
// GetToolInfo() after this to force the tool to be
// materialized.
- AddTool(config_obj *config_proto.Config,
+ AddTool(ctx context.Context, config_obj *config_proto.Config,
tool *artifacts_proto.Tool, opts ToolOptions) error
// Remove the tool from the inventory.
diff --git a/services/inventory/dummy.go b/services/inventory/dummy.go
index 5104d39a8b5..258ea3a43aa 100644
--- a/services/inventory/dummy.go
+++ b/services/inventory/dummy.go
@@ -87,7 +87,9 @@ func (self *Dummy) Get() *artifacts_proto.ThirdParty {
return proto.Clone(self.binaries).(*artifacts_proto.ThirdParty)
}
-func (self *Dummy) ProbeToolInfo(name string) (*artifacts_proto.Tool, error) {
+func (self *Dummy) ProbeToolInfo(
+ ctx context.Context, config_obj *config_proto.Config,
+ name string) (*artifacts_proto.Tool, error) {
for _, tool := range self.Get().Tools {
if tool.Name == name {
return tool, nil
@@ -248,11 +250,13 @@ func getGithubRelease(ctx context.Context, Client HTTPClient,
return "", errors.New("Release not found from github API " + url)
}
-func (self *Dummy) AddTool(config_obj *config_proto.Config,
+func (self *Dummy) AddTool(
+ ctx context.Context, config_obj *config_proto.Config,
tool_request *artifacts_proto.Tool,
opts services.ToolOptions) error {
if opts.Upgrade {
- existing_tool, err := self.ProbeToolInfo(tool_request.Name)
+ existing_tool, err := self.ProbeToolInfo(
+ ctx, config_obj, tool_request.Name)
if err == nil {
// Ignore the request if the existing
// definition is better than the new one.
diff --git a/services/inventory/fixtures/TestGihubToolServedLocally.golden b/services/inventory/fixtures/TestGihubToolServedLocally.golden
index 2d90f8fb7e0..f03054bd19f 100644
--- a/services/inventory/fixtures/TestGihubToolServedLocally.golden
+++ b/services/inventory/fixtures/TestGihubToolServedLocally.golden
@@ -19,6 +19,7 @@
"total_queries": 1
},
"Tool": {
+ "artifact": "TestArtifact",
"filename": "file.exe",
"filestore_path": "dbdbc5e2ae775342ae9189803757a07b20daf0b04a25cda9d97a99785d75ec3b",
"github_asset_regex": "windows-amd64.exe",
@@ -27,6 +28,15 @@
"name": "SampleTool",
"serve_locally": true,
"serve_url": "https://localhost:8000/public/dbdbc5e2ae775342ae9189803757a07b20daf0b04a25cda9d97a99785d75ec3b",
- "url": "htttp://www.example.com/file.exe"
+ "url": "htttp://www.example.com/file.exe",
+ "versions": [
+ {
+ "artifact": "TestArtifact",
+ "github_asset_regex": "windows-amd64.exe",
+ "github_project": "Velocidex/velociraptor",
+ "name": "SampleTool",
+ "serve_locally": true
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/services/inventory/fixtures/TestGihubTools.golden b/services/inventory/fixtures/TestGihubTools.golden
index 4024dc0ab75..893cdf28fc1 100644
--- a/services/inventory/fixtures/TestGihubTools.golden
+++ b/services/inventory/fixtures/TestGihubTools.golden
@@ -7,7 +7,14 @@
"hash": "3c03cf5341a1e078c438f31852e1587a70cc9f91ee02eda315dd231aba0a0ab1",
"name": "SampleTool",
"serve_url": "htttp://www.example.com/file.exe",
- "url": "htttp://www.example.com/file.exe"
+ "url": "htttp://www.example.com/file.exe",
+ "versions": [
+ {
+ "github_asset_regex": "windows-amd64.exe",
+ "github_project": "Velocidex/velociraptor",
+ "name": "SampleTool"
+ }
+ ]
},
"VQLCollectorArgs": {
"env": [
diff --git a/services/inventory/fixtures/TestGihubToolsUninitialized.golden b/services/inventory/fixtures/TestGihubToolsUninitialized.golden
index 4d9c3e85e0f..cc0c79b27f0 100644
--- a/services/inventory/fixtures/TestGihubToolsUninitialized.golden
+++ b/services/inventory/fixtures/TestGihubToolsUninitialized.golden
@@ -19,6 +19,7 @@
"total_queries": 1
},
"Tool": {
+ "artifact": "TestArtifact",
"filename": "file.exe",
"filestore_path": "dbdbc5e2ae775342ae9189803757a07b20daf0b04a25cda9d97a99785d75ec3b",
"github_asset_regex": "windows-amd64.exe",
@@ -26,6 +27,14 @@
"hash": "3c03cf5341a1e078c438f31852e1587a70cc9f91ee02eda315dd231aba0a0ab1",
"name": "SampleTool",
"serve_url": "htttp://www.example.com/file.exe",
- "url": "htttp://www.example.com/file.exe"
+ "url": "htttp://www.example.com/file.exe",
+ "versions": [
+ {
+ "artifact": "TestArtifact",
+ "github_asset_regex": "windows-amd64.exe",
+ "github_project": "Velocidex/velociraptor",
+ "name": "SampleTool"
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/services/inventory/inventory.go b/services/inventory/inventory.go
index 5dac4d00c26..9f140eac7bd 100644
--- a/services/inventory/inventory.go
+++ b/services/inventory/inventory.go
@@ -72,6 +72,7 @@ type githubAssets struct {
type InventoryService struct {
mu sync.Mutex
binaries *artifacts_proto.ThirdParty
+ versions map[string][]*artifacts_proto.Tool
Client HTTPClient
Clock utils.Clock
}
@@ -92,15 +93,42 @@ func (self *InventoryService) ClearForTests() {
self.binaries = &artifacts_proto.ThirdParty{}
}
-func (self *InventoryService) ProbeToolInfo(name string) (*artifacts_proto.Tool, error) {
+func (self *InventoryService) ProbeToolInfo(
+ ctx context.Context, config_obj *config_proto.Config,
+ name string) (*artifacts_proto.Tool, error) {
for _, tool := range self.Get().Tools {
if tool.Name == name {
- return tool, nil
+ return self.AddAllVersions(ctx, config_obj, tool), nil
}
}
+
return nil, errors.New("Not Found")
}
+// Enrich the tool definition with all known versions of this tool.
+func (self *InventoryService) AddAllVersions(
+ ctx context.Context, config_obj *config_proto.Config,
+ tool *artifacts_proto.Tool) *artifacts_proto.Tool {
+ self.mu.Lock()
+ defer self.mu.Unlock()
+
+ return self.addAllVersions(ctx, config_obj, tool)
+}
+
+func (self *InventoryService) addAllVersions(
+ ctx context.Context, config_obj *config_proto.Config,
+ tool *artifacts_proto.Tool) *artifacts_proto.Tool {
+ result := proto.Clone(tool).(*artifacts_proto.Tool)
+
+ versions, _ := self.versions[tool.Name]
+ result.Versions = nil
+ for _, v := range versions {
+ result.Versions = append(result.Versions, v)
+ }
+
+ return result
+}
+
// Gets the tool information from the inventory. If the tool is not
// already downloaded, we download it and update the hashes.
func (self *InventoryService) GetToolInfo(
@@ -127,7 +155,9 @@ func (self *InventoryService) GetToolInfo(
return nil, err
}
}
- return proto.Clone(item).(*artifacts_proto.Tool), nil
+ // Already holding the mutex here - call the lock free
+ // version.
+ return self.addAllVersions(ctx, config_obj, item), nil
}
}
return nil, fmt.Errorf("Tool %v not declared in inventory.", tool)
@@ -274,10 +304,47 @@ func (self *InventoryService) RemoveTool(
return db.SetSubject(config_obj, paths.ThirdPartyInventory, self.binaries)
}
-func (self *InventoryService) AddTool(config_obj *config_proto.Config,
+func (self *InventoryService) UpdateVersion(tool_request *artifacts_proto.Tool) {
+ self.mu.Lock()
+ defer self.mu.Unlock()
+
+ // Update the list of version for this tool, replacing existing
+ // definitions.
+ versions, _ := self.versions[tool_request.Name]
+ version_known := false
+ for idx, v := range versions {
+ if v.Artifact == tool_request.Artifact {
+ versions[idx] = tool_request
+ version_known = true
+ break
+ }
+ }
+
+ if !version_known {
+ versions = append(versions, tool_request)
+ }
+ self.versions[tool_request.Name] = versions
+}
+
+// This gets called by the repository for each artifact loaded to
+// inform us about any tools it contains. The InventoryService looks
+// at its current definition for the tool in the inventory to see if
+// it needs to upgrade the definition or add a new entry to the
+// inventory automatically.
+func (self *InventoryService) AddTool(
+ ctx context.Context, config_obj *config_proto.Config,
tool_request *artifacts_proto.Tool, opts services.ToolOptions) error {
+
+ tool_request.Versions = nil
+
+ // Keep a reference to all known versions of this tool. We keep
+ // the clean definitions from the artifact together, so we can
+ // always reset back to them.
+ self.UpdateVersion(tool_request)
+
if opts.Upgrade {
- existing_tool, err := self.ProbeToolInfo(tool_request.Name)
+ existing_tool, err := self.ProbeToolInfo(
+ ctx, config_obj, tool_request.Name)
if err == nil {
// Ignore the request if the existing
// definition is better than the new one.
@@ -391,6 +458,7 @@ func NewInventoryService(
inventory_service := &InventoryService{
Clock: utils.RealClock{},
binaries: &artifacts_proto.ThirdParty{},
+ versions: make(map[string][]*artifacts_proto.Tool),
// Use the VQL http client so it can accept the same certs.
Client: default_client,
}
diff --git a/services/inventory/inventory_test.go b/services/inventory/inventory_test.go
index e3ca8ace35e..6d257e00354 100644
--- a/services/inventory/inventory_test.go
+++ b/services/inventory/inventory_test.go
@@ -62,7 +62,7 @@ func (self *ServicesTestSuite) TestGihubTools() {
inventory, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory.AddTool(
+ err = inventory.AddTool(ctx,
self.ConfigObj, &artifacts_proto.Tool{
Name: tool_name,
GithubProject: "Velocidex/velociraptor",
@@ -179,6 +179,10 @@ tools:
tool, err := inventory_service.GetToolInfo(ctx, self.ConfigObj, tool_name)
assert.NoError(self.T(), err)
+ // Make sure the tool contains the version block
+ assert.Equal(self.T(), 1, len(tool.Versions))
+ assert.Equal(self.T(), "TestArtifact", tool.Versions[0].Artifact)
+
// Make sure the tool is served directly from upstream.
assert.Equal(self.T(), response[0].Env[2].Key, "Tool_SampleTool_URL")
assert.Equal(self.T(), response[0].Env[2].Value, "htttp://www.example.com/file.exe")
@@ -210,7 +214,8 @@ func (self *ServicesTestSuite) TestUpgrade() {
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(self.ConfigObj, tool_definition, services.ToolOptions{})
+ err = inventory_service.AddTool(ctx, self.ConfigObj,
+ tool_definition, services.ToolOptions{})
assert.NoError(self.T(), err)
tool, err := inventory_service.GetToolInfo(ctx, self.ConfigObj, tool_name)
@@ -223,7 +228,8 @@ func (self *ServicesTestSuite) TestUpgrade() {
// Now force the tool to update by re-adding it but this time it is a new version.
self.installGitHubMockVersion2()
- err = inventory_service.AddTool(self.ConfigObj, tool_definition, services.ToolOptions{})
+ err = inventory_service.AddTool(ctx, self.ConfigObj, tool_definition,
+ services.ToolOptions{})
assert.NoError(self.T(), err)
// Check the tool information.
@@ -308,19 +314,20 @@ tools:
_, err = repository.LoadYaml(test_artifact, services.ValidateArtifact, services.ArtifactIsBuiltIn)
assert.NoError(self.T(), err)
- _, pres := repository.Get(self.ConfigObj, "TestArtifact")
+ ctx := self.Ctx
+ _, pres := repository.Get(ctx, self.ConfigObj, "TestArtifact")
assert.True(self.T(), pres)
_, err = repository.LoadYaml(test_artifact2, services.ValidateArtifact, services.ArtifactIsBuiltIn)
assert.NoError(self.T(), err)
- _, pres = repository.Get(self.ConfigObj, "TestArtifact2")
+ _, pres = repository.Get(ctx, self.ConfigObj, "TestArtifact2")
assert.True(self.T(), pres)
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- tool, err := inventory_service.ProbeToolInfo("SampleTool")
+ tool, err := inventory_service.ProbeToolInfo(ctx, self.ConfigObj, "SampleTool")
assert.NoError(self.T(), err)
// The tool definition retains the original URL
@@ -343,7 +350,7 @@ tools:
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(self.ConfigObj,
+ err = inventory_service.AddTool(self.Ctx, self.ConfigObj,
&artifacts_proto.Tool{
Name: "SampleTool",
Hash: "XXXXX",
@@ -359,10 +366,10 @@ tools:
_, err = repository.LoadYaml(test_artifact, services.ValidateArtifact, services.ArtifactIsBuiltIn)
assert.NoError(self.T(), err)
- _, pres := repository.Get(self.ConfigObj, "TestArtifact")
+ _, pres := repository.Get(self.Ctx, self.ConfigObj, "TestArtifact")
assert.True(self.T(), pres)
- tool, err := inventory_service.ProbeToolInfo("SampleTool")
+ tool, err := inventory_service.ProbeToolInfo(self.Ctx, self.ConfigObj, "SampleTool")
assert.NoError(self.T(), err)
assert.Equal(self.T(), tool.Url, "")
@@ -389,7 +396,7 @@ tools:
_, err = repository.LoadYaml(test_artifact, services.ValidateArtifact, services.ArtifactIsBuiltIn)
assert.NoError(self.T(), err)
- _, pres := repository.Get(self.ConfigObj, "TestArtifact")
+ _, pres := repository.Get(self.Ctx, self.ConfigObj, "TestArtifact")
assert.True(self.T(), pres)
// The admin sets a very minimal tool definition which would
@@ -398,14 +405,15 @@ tools:
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(self.ConfigObj,
+ err = inventory_service.AddTool(self.Ctx, self.ConfigObj,
&artifacts_proto.Tool{
Name: "SampleTool",
Hash: "XXXXX",
}, services.ToolOptions{AdminOverride: true})
assert.NoError(self.T(), err)
- tool, err := inventory_service.ProbeToolInfo("SampleTool")
+ tool, err := inventory_service.ProbeToolInfo(
+ self.Ctx, self.ConfigObj, "SampleTool")
assert.NoError(self.T(), err)
assert.Equal(self.T(), tool.Url, "")
@@ -418,21 +426,22 @@ func (self *ServicesTestSuite) TestAdminOverrideAdminSet() {
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(self.ConfigObj,
+ err = inventory_service.AddTool(self.Ctx, self.ConfigObj,
&artifacts_proto.Tool{
Name: "SampleTool",
Hash: "XXXXX",
}, services.ToolOptions{AdminOverride: true})
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(self.ConfigObj,
+ err = inventory_service.AddTool(self.Ctx, self.ConfigObj,
&artifacts_proto.Tool{
Name: "SampleTool",
Hash: "YYYYY",
}, services.ToolOptions{AdminOverride: true})
assert.NoError(self.T(), err)
- tool, err := inventory_service.ProbeToolInfo("SampleTool")
+ tool, err := inventory_service.ProbeToolInfo(
+ self.Ctx, self.ConfigObj, "SampleTool")
assert.NoError(self.T(), err)
assert.Equal(self.T(), tool.Url, "")
diff --git a/services/journal.go b/services/journal.go
index 67a05e52d54..aea99a0f9a8 100644
--- a/services/journal.go
+++ b/services/journal.go
@@ -51,24 +51,25 @@ type JournalService interface {
AppendToResultSet(config_obj *config_proto.Config,
path api.FSPathSpec, rows []*ordereddict.Dict) error
- Broadcast(config_obj *config_proto.Config,
+ Broadcast(ctx context.Context, config_obj *config_proto.Config,
rows []*ordereddict.Dict, name, client_id, flows_id string) error
// Push the rows to the event artifact queue
- PushRowsToArtifact(config_obj *config_proto.Config,
+ PushRowsToArtifact(ctx context.Context, config_obj *config_proto.Config,
rows []*ordereddict.Dict, name, client_id, flows_id string) error
// An optimization around PushRowsToArtifact where rows are
// already serialized in JSONL
PushJsonlToArtifact(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
jsonl []byte, row_count int,
name, client_id, flows_id string) error
// Push the rows to the event artifact queue with a potential
// unspecified delay. Internally these rows will be batched until
// a convenient time to send them.
- PushRowsToArtifactAsync(config_obj *config_proto.Config,
+ PushRowsToArtifactAsync(
+ ctx context.Context, config_obj *config_proto.Config,
row *ordereddict.Dict, name string)
// Sets the clock for tests
diff --git a/services/journal/journal.go b/services/journal/journal.go
index 3b4c141d249..52116759df1 100644
--- a/services/journal/journal.go
+++ b/services/journal/journal.go
@@ -46,8 +46,8 @@ func (self *JournalService) GetWatchers() []string {
return self.qm.GetWatchers()
}
-func (self *JournalService) publishWatchers() {
- self.PushRowsToArtifact(self.config_obj,
+func (self *JournalService) publishWatchers(ctx context.Context) {
+ self.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("Events", self.GetWatchers())},
"Server.Internal.MasterRegistrations", "server", "")
@@ -69,13 +69,13 @@ func (self *JournalService) Watch(
})
// Advertise new watchers
- self.publishWatchers()
+ self.publishWatchers(ctx)
return res, func() {
cancel()
// Advertise that a watcher was removed.
- self.publishWatchers()
+ self.publishWatchers(ctx)
}
}
@@ -154,11 +154,11 @@ func (self *JournalService) AppendJsonlToResultSet(
}
func (self *JournalService) PushRowsToArtifactAsync(
- config_obj *config_proto.Config, row *ordereddict.Dict,
+ ctx context.Context, config_obj *config_proto.Config, row *ordereddict.Dict,
artifact string) {
go func() {
- err := self.PushRowsToArtifact(config_obj, []*ordereddict.Dict{row},
+ err := self.PushRowsToArtifact(ctx, config_obj, []*ordereddict.Dict{row},
artifact, "server", "")
if err != nil {
logger := logging.GetLogger(self.config_obj, &logging.FrontendComponent)
@@ -168,13 +168,13 @@ func (self *JournalService) PushRowsToArtifactAsync(
}
func (self *JournalService) Broadcast(
- config_obj *config_proto.Config, rows []*ordereddict.Dict,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ rows []*ordereddict.Dict, artifact, client_id, flows_id string) error {
if self == nil || self.qm == nil {
return notInitializedError
}
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flows_id, artifact)
if err != nil {
return err
@@ -185,10 +185,10 @@ func (self *JournalService) Broadcast(
}
func (self *JournalService) PushJsonlToArtifact(
- config_obj *config_proto.Config, jsonl []byte, row_count int,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ jsonl []byte, row_count int, artifact, client_id, flows_id string) error {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flows_id, artifact)
if err != nil {
return err
@@ -213,10 +213,10 @@ func (self *JournalService) PushJsonlToArtifact(
}
func (self *JournalService) PushRowsToArtifact(
- config_obj *config_proto.Config, rows []*ordereddict.Dict,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ rows []*ordereddict.Dict, artifact, client_id, flows_id string) error {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flows_id, artifact)
if err != nil {
return err
diff --git a/services/journal/journal_test.go b/services/journal/journal_test.go
index ea6789b8df1..a7e05a4df71 100644
--- a/services/journal/journal_test.go
+++ b/services/journal/journal_test.go
@@ -72,8 +72,9 @@ func (self *JournalTestSuite) TestJournalWriting() {
snapshot := vtesting.GetMetrics(self.T(), ".")
// Write 10 rows in series
+ ctx := self.Ctx
for i := 0; i < 10; i++ {
- err = journal.PushRowsToArtifact(self.ConfigObj,
+ err = journal.PushRowsToArtifact(ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("Foo", "Bar").
Set("i", i),
@@ -125,7 +126,7 @@ func (self *JournalTestSuite) TestJournalJsonlWriting() {
// Write 10 rows in series
for i := 0; i < 10; i++ {
- err = journal.PushJsonlToArtifact(self.ConfigObj,
+ err = journal.PushJsonlToArtifact(self.Ctx, self.ConfigObj,
[]byte(fmt.Sprintf("{\"For\":%q,\"i\":%d}\n", "Bar", i)), 1,
"System.Flow.Completion", "C.1234", "")
assert.NoError(self.T(), err)
diff --git a/services/journal/replication.go b/services/journal/replication.go
index 849dffc3be2..d8a608f4721 100644
--- a/services/journal/replication.go
+++ b/services/journal/replication.go
@@ -199,7 +199,7 @@ func (self *ReplicationService) startAsyncLoop(
for k, v := range todo {
// Ignore errors since there is no way to report
// to the caller.
- self.PushJsonlToArtifact(
+ self.PushJsonlToArtifact(ctx,
config_obj, v.Bytes(), v.row_count, k,
"server", "")
}
@@ -431,15 +431,15 @@ func (self *ReplicationService) AppendToResultSet(
}
func (self *ReplicationService) Broadcast(
- config_obj *config_proto.Config, rows []*ordereddict.Dict,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ rows []*ordereddict.Dict, artifact, client_id, flows_id string) error {
return notInitializedError
}
func (self *ReplicationService) PushRowsToArtifactAsync(
- config_obj *config_proto.Config, row *ordereddict.Dict,
- artifact string) {
+ ctx context.Context, config_obj *config_proto.Config,
+ row *ordereddict.Dict, artifact string) {
self.mu.Lock()
defer self.mu.Unlock()
@@ -457,10 +457,10 @@ func (self *ReplicationService) PushRowsToArtifactAsync(
}
func (self *ReplicationService) pushRowsToLocalQueueManager(
- config_obj *config_proto.Config, rows []*ordereddict.Dict,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ rows []*ordereddict.Dict, artifact, client_id, flows_id string) error {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flows_id, artifact)
if err != nil {
return err
@@ -485,10 +485,10 @@ func (self *ReplicationService) pushRowsToLocalQueueManager(
}
func (self *ReplicationService) pushJsonlToLocalQueueManager(
- config_obj *config_proto.Config, jsonl []byte, row_count int,
- artifact, client_id, flows_id string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ jsonl []byte, row_count int, artifact, client_id, flows_id string) error {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flows_id, artifact)
if err != nil {
return err
@@ -513,10 +513,11 @@ func (self *ReplicationService) pushJsonlToLocalQueueManager(
}
func (self *ReplicationService) PushJsonlToArtifact(
- config_obj *config_proto.Config, jsonl []byte, row_count int,
+ ctx context.Context, config_obj *config_proto.Config,
+ jsonl []byte, row_count int,
artifact, client_id, flow_id string) error {
- err := self.pushJsonlToLocalQueueManager(
+ err := self.pushJsonlToLocalQueueManager(ctx,
config_obj, jsonl, row_count, artifact,
client_id, flow_id)
if err != nil {
@@ -555,7 +556,7 @@ func (self *ReplicationService) PushJsonlToArtifact(
}
func (self *ReplicationService) PushRowsToArtifact(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
rows []*ordereddict.Dict, artifact, client_id, flow_id string) error {
serialized, err := json.MarshalJsonl(rows)
@@ -564,7 +565,7 @@ func (self *ReplicationService) PushRowsToArtifact(
}
replicationItemSize.Observe(float64(len(serialized)))
- err = self.pushRowsToLocalQueueManager(
+ err = self.pushRowsToLocalQueueManager(ctx,
config_obj, rows, artifact, client_id, flow_id)
if err != nil {
return err
diff --git a/services/journal/replication_test.go b/services/journal/replication_test.go
index 6d584afcf69..20b7f793b62 100644
--- a/services/journal/replication_test.go
+++ b/services/journal/replication_test.go
@@ -173,7 +173,7 @@ func (self *ReplicationTestSuite) TestSendingEvents() {
Set("Events", []interface{}{"Test.Artifact"}))
events = nil
- err = journal_service.PushRowsToArtifact(self.ConfigObj,
+ err = journal_service.PushRowsToArtifact(self.Ctx, self.ConfigObj,
my_event, "Test.Artifact", "C.1234", "F.123")
assert.NoError(self.T(), err)
@@ -199,7 +199,7 @@ func (self *ReplicationTestSuite) TestSendingEvents() {
// is often on the critical path. We just dump 1000 messages
// into the queue - this should overflow into the file.
for i := 0; i < 1000; i++ {
- err = journal_service.PushRowsToArtifact(self.ConfigObj,
+ err = journal_service.PushRowsToArtifact(self.Ctx, self.ConfigObj,
my_event, "Test.Artifact", "C.1234", "F.123")
assert.NoError(self.T(), err)
}
diff --git a/services/labels/labels.go b/services/labels/labels.go
index 11226645c80..9a6ecdf4f3f 100644
--- a/services/labels/labels.go
+++ b/services/labels/labels.go
@@ -177,7 +177,7 @@ func (self *Labeler) IsLabelSet(
}
func (self *Labeler) notifyClient(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
client_id, new_label, operation string) error {
// Notify other frontends about this change.
journal, err := services.GetJournal(config_obj)
@@ -185,7 +185,7 @@ func (self *Labeler) notifyClient(
return err
}
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("client_id", client_id).
Set("Operation", operation).
@@ -231,7 +231,7 @@ func (self *Labeler) SetClientLabel(
// Cache the new record.
self.lru.Set(client_id, cached)
- err = self.notifyClient(config_obj, client_id, new_label, "Add")
+ err = self.notifyClient(ctx, config_obj, client_id, new_label, "Add")
if err != nil {
return err
}
@@ -286,7 +286,7 @@ func (self *Labeler) RemoveClientLabel(
// Cache the new record.
self.lru.Set(client_id, cached)
- err = self.notifyClient(config_obj, client_id, new_label, "Remove")
+ err = self.notifyClient(ctx, config_obj, client_id, new_label, "Remove")
if err != nil {
return err
}
diff --git a/services/launcher.go b/services/launcher.go
index 06db1459ac2..2d165e5cbc3 100644
--- a/services/launcher.go
+++ b/services/launcher.go
@@ -95,7 +95,7 @@ type Launcher interface {
// Calculates the dependent artifacts
GetDependentArtifacts(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
repository Repository,
names []string) ([]string, error)
diff --git a/services/launcher/compiler.go b/services/launcher/compiler.go
index eb14f9d7672..68a1917ac80 100644
--- a/services/launcher/compiler.go
+++ b/services/launcher/compiler.go
@@ -34,7 +34,7 @@ func maybeEscape(name string) string {
}
func (self *Launcher) CompileSingleArtifact(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
options services.CompilerOptions,
artifact *artifacts_proto.Artifact,
result *actions_proto.VQLCollectorArgs) error {
@@ -175,7 +175,7 @@ LET %v <= if(
result.IopsLimit = artifact.Resources.IopsLimit
}
- err := resolveImports(config_obj, artifact, result)
+ err := resolveImports(ctx, config_obj, artifact, result)
if err != nil {
return err
}
@@ -183,7 +183,8 @@ LET %v <= if(
return mergeSources(config_obj, options, artifact, result)
}
-func resolveImports(config_obj *config_proto.Config,
+func resolveImports(
+ ctx context.Context, config_obj *config_proto.Config,
artifact *artifacts_proto.Artifact,
result *actions_proto.VQLCollectorArgs) error {
// Resolve imports if needed. First check if the artifact
@@ -224,7 +225,7 @@ func resolveImports(config_obj *config_proto.Config,
for _, imported := range artifact.Imports {
scope := vql_subsystem.MakeScope()
- dependent_artifact, pres := global_repo.Get(config_obj, imported)
+ dependent_artifact, pres := global_repo.Get(ctx, config_obj, imported)
if !pres {
return fmt.Errorf("Artifact %v imports %v which is not known.",
artifact.Name, imported)
@@ -346,7 +347,7 @@ func mergeSources(
// artifacts are found, then recursivly determine their dependencies
// etc.
func GetQueryDependencies(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
repository services.Repository,
query string,
depth int,
@@ -357,7 +358,7 @@ func GetQueryDependencies(
for _, hit := range artifact_in_query_regex.
FindAllStringSubmatch(query, -1) {
artifact_name := hit[1]
- dep, pres := repository.Get(config_obj, artifact_name)
+ dep, pres := repository.Get(ctx, config_obj, artifact_name)
if !pres {
return errors.New(
fmt.Sprintf("Unknown artifact reference %s",
@@ -379,7 +380,7 @@ func GetQueryDependencies(
}
dependency[imp] = depth
- imported_artifact, pres := repository.Get(config_obj, imp)
+ imported_artifact, pres := repository.Get(ctx, config_obj, imp)
if !pres {
return fmt.Errorf(
"Imported Artifact %v not found (needed by %v)",
@@ -388,7 +389,7 @@ func GetQueryDependencies(
// If the exported section depends on other artifacts,
// then add them too.
- err := GetQueryDependencies(config_obj, repository,
+ err := GetQueryDependencies(ctx, config_obj, repository,
imported_artifact.Export, 0, dependency)
if err != nil {
return err
@@ -397,20 +398,20 @@ func GetQueryDependencies(
// Now search the referred to artifact's query for its
// own dependencies.
- err := GetQueryDependencies(
+ err := GetQueryDependencies(ctx,
config_obj, repository, dep.Precondition, depth+1, dependency)
if err != nil {
return err
}
for _, source := range dep.Sources {
- err := GetQueryDependencies(config_obj, repository,
+ err := GetQueryDependencies(ctx, config_obj, repository,
source.Precondition, depth+1, dependency)
if err != nil {
return err
}
- err = GetQueryDependencies(config_obj, repository,
+ err = GetQueryDependencies(ctx, config_obj, repository,
source.Query, depth+1, dependency)
if err != nil {
return err
@@ -430,7 +431,7 @@ func PopulateArtifactsVQLCollectorArgs(
request *actions_proto.VQLCollectorArgs) error {
dependencies := make(map[string]int)
for _, query := range request.Query {
- err := GetQueryDependencies(config_obj, repository,
+ err := GetQueryDependencies(ctx, config_obj, repository,
query.VQL, 0, dependencies)
if err != nil {
return err
@@ -445,7 +446,7 @@ func PopulateArtifactsVQLCollectorArgs(
sort.Strings(dep_names)
for _, k := range dep_names {
- artifact, pres := repository.Get(config_obj, k)
+ artifact, pres := repository.Get(ctx, config_obj, k)
if pres {
// Filter the artifact to contain only
// essential data.
@@ -532,9 +533,8 @@ func PopulateArtifactsVQLCollectorArgs(
// request. This function is used to fill in a copy of the dependent
// artifacts in the client request.
func (self *Launcher) GetDependentArtifacts(
- config_obj *config_proto.Config,
- repository services.Repository,
- names []string) ([]string, error) {
+ ctx context.Context, config_obj *config_proto.Config,
+ repository services.Repository, names []string) ([]string, error) {
dependency := make(map[string]int)
@@ -548,13 +548,13 @@ func (self *Launcher) GetDependentArtifacts(
continue
}
- _, pres = repository.Get(config_obj, name)
+ _, pres = repository.Get(ctx, config_obj, name)
if !pres {
return nil, fmt.Errorf(
"GetDependentArtifacts: Artifact %v not found", name)
}
- err := GetQueryDependencies(config_obj, repository,
+ err := GetQueryDependencies(ctx, config_obj, repository,
fmt.Sprintf("SELECT * FROM Artifact.%s()", name), 0, dependency)
if err != nil {
return nil, err
diff --git a/services/launcher/delete.go b/services/launcher/delete.go
index 971b67e5112..7b7d3dfb1ef 100644
--- a/services/launcher/delete.go
+++ b/services/launcher/delete.go
@@ -70,7 +70,7 @@ func (self *Launcher) DeleteFlow(
// Remove all result sets from artifacts.
for _, artifact_name := range collection_context.ArtifactsWithResults {
- path_manager, err := artifact_paths.NewArtifactPathManager(
+ path_manager, err := artifact_paths.NewArtifactPathManager(ctx,
config_obj, client_id, flow_id, artifact_name)
if err != nil {
continue
@@ -197,7 +197,7 @@ func (self *Launcher) DeleteEvents(
start_time, end_time time.Time,
really_do_it bool) ([]*services.DeleteFlowResponse, error) {
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, "", artifact)
if err != nil {
return nil, err
@@ -240,7 +240,7 @@ func (self *Launcher) DeleteEvents(
}
}
- log_path_manager, err := artifacts.NewArtifactLogPathManager(
+ log_path_manager, err := artifacts.NewArtifactLogPathManager(ctx,
config_obj, client_id, "", artifact)
if err != nil {
return nil, err
diff --git a/services/launcher/launcher.go b/services/launcher/launcher.go
index 2f61dd40da4..6c387300cc4 100644
--- a/services/launcher/launcher.go
+++ b/services/launcher/launcher.go
@@ -202,11 +202,11 @@ func (self *Launcher) CompileCollectorArgs(
var artifact *artifacts_proto.Artifact = nil
if collector_request.AllowCustomOverrides {
- artifact, _ = repository.Get(config_obj, "Custom."+spec.Artifact)
+ artifact, _ = repository.Get(ctx, config_obj, "Custom."+spec.Artifact)
}
if artifact == nil {
- artifact, _ = repository.Get(config_obj, spec.Artifact)
+ artifact, _ = repository.Get(ctx, config_obj, spec.Artifact)
}
if artifact == nil {
@@ -373,7 +373,8 @@ func (self *Launcher) GetVQLCollectorArgs(
options services.CompilerOptions) (*actions_proto.VQLCollectorArgs, error) {
vql_collector_args := &actions_proto.VQLCollectorArgs{}
- err := self.CompileSingleArtifact(config_obj, options, artifact, vql_collector_args)
+ err := self.CompileSingleArtifact(ctx, config_obj,
+ options, artifact, vql_collector_args)
if err != nil {
return nil, err
}
@@ -432,7 +433,7 @@ func (self *Launcher) EnsureToolsDeclared(
// itself.
logger.Info("Adding tool %v from artifact %v",
tool.Name, artifact.Name)
- err = inventory.AddTool(
+ err = inventory.AddTool(ctx,
config_obj, tool,
services.ToolOptions{
Upgrade: true,
diff --git a/services/launcher/launcher_test.go b/services/launcher/launcher_test.go
index 74fc843fe2b..033ca1c06c7 100644
--- a/services/launcher/launcher_test.go
+++ b/services/launcher/launcher_test.go
@@ -154,7 +154,7 @@ func (self *LauncherTestSuite) TestCompilingWithTools() {
inventory_service, err := services.GetInventory(self.ConfigObj)
assert.NoError(self.T(), err)
- err = inventory_service.AddTool(
+ err = inventory_service.AddTool(ctx,
self.ConfigObj, &artifacts_proto.Tool{
Name: "Tool1",
// This will force Velociraptor to generate a stable
@@ -214,7 +214,7 @@ func (self *LauncherTestSuite) TestGetDependentArtifacts() {
launcher, err := services.GetLauncher(self.ConfigObj)
assert.NoError(self.T(), err)
- res, err := launcher.GetDependentArtifacts(self.ConfigObj,
+ res, err := launcher.GetDependentArtifacts(self.Ctx, self.ConfigObj,
repository, []string{"Test.Artifact.Deps2"})
assert.NoError(self.T(), err)
@@ -253,7 +253,7 @@ func (self *LauncherTestSuite) TestGetDependentArtifactsWithImports() {
launcher, err := services.GetLauncher(self.ConfigObj)
assert.NoError(self.T(), err)
- res, err := launcher.GetDependentArtifacts(self.ConfigObj,
+ res, err := launcher.GetDependentArtifacts(self.Ctx, self.ConfigObj,
repository, []string{"Custom.CallArtifactWithImports"})
assert.NoError(self.T(), err)
diff --git a/services/notebook/initial.go b/services/notebook/initial.go
index 1a1f45bfe71..86e3d5dceaa 100644
--- a/services/notebook/initial.go
+++ b/services/notebook/initial.go
@@ -155,7 +155,7 @@ func getCellsForEvents(ctx context.Context,
return nil
}
- result := getCustomCells(config_obj, repository,
+ result := getCustomCells(ctx, config_obj, repository,
artifact_name, notebook_metadata)
// If there are no custom cells, add the default cell.
@@ -199,6 +199,7 @@ LIMIT 50
}
func getCustomCells(
+ ctx context.Context,
config_obj *config_proto.Config,
repository services.Repository,
source string,
@@ -206,7 +207,7 @@ func getCustomCells(
var result []*api_proto.NotebookCellRequest
// Check if the artifact has custom notebook cells defined.
- artifact_source, pres := repository.GetSource(config_obj, source)
+ artifact_source, pres := repository.GetSource(ctx, config_obj, source)
if !pres {
return nil
}
@@ -324,7 +325,7 @@ WHERE FlowState =~ 'Finished'
LIMIT 1000
`})
- return getDefaultCellsForSources(config_obj, sources, notebook_metadata)
+ return getDefaultCellsForSources(ctx, config_obj, sources, notebook_metadata)
}
func getCellsForFlow(ctx context.Context,
@@ -362,10 +363,12 @@ SELECT * FROM flow_logs(client_id=ClientId, flow_id=FlowId)
`,
})
- return getDefaultCellsForSources(config_obj, sources, notebook_metadata)
+ return getDefaultCellsForSources(
+ ctx, config_obj, sources, notebook_metadata)
}
func getDefaultCellsForSources(
+ ctx context.Context,
config_obj *config_proto.Config,
sources []string,
notebook_metadata *api_proto.NotebookMetadata) []*api_proto.NotebookCellRequest {
@@ -383,13 +386,13 @@ func getDefaultCellsForSources(
var result []*api_proto.NotebookCellRequest
for _, source := range sources {
- artifact, pres := repository.Get(config_obj, source)
+ artifact, pres := repository.Get(ctx, config_obj, source)
if pres {
notebook_metadata.ColumnTypes = append(notebook_metadata.ColumnTypes,
artifact.ColumnTypes...)
}
- new_cells := getCustomCells(config_obj, repository,
+ new_cells := getCustomCells(ctx, config_obj, repository,
source, notebook_metadata)
result = append(result, new_cells...)
diff --git a/services/notebook/notebook.go b/services/notebook/notebook.go
index 0b6d79c1a45..1cb034d323d 100644
--- a/services/notebook/notebook.go
+++ b/services/notebook/notebook.go
@@ -133,7 +133,7 @@ func (self *NotebookManager) CancelNotebookCell(
if err != nil {
return err
}
- return notifier.NotifyListener(self.config_obj, cell_id,
+ return notifier.NotifyListener(ctx, self.config_obj, cell_id,
"CancelNotebookCell")
}
diff --git a/services/notifications.go b/services/notifications.go
index 53c22e6846b..bf55bcfe843 100644
--- a/services/notifications.go
+++ b/services/notifications.go
@@ -41,13 +41,15 @@ type Notifier interface {
// Send a notification to a specific listener based on its id
// that was registered above.
- NotifyListener(config_obj *config_proto.Config, id, tag string) error
+ NotifyListener(ctx context.Context, config_obj *config_proto.Config,
+ id, tag string) error
// Notify a directly connected listener.
NotifyDirectListener(id string)
// Notify in the near future - no guarantee of delivery.
- NotifyListenerAsync(config_obj *config_proto.Config, id, tag string)
+ NotifyListenerAsync(ctx context.Context,
+ config_obj *config_proto.Config, id, tag string)
// Check if there is someone listening for the specified id. This
// method queries all minion nodes to check if the client is
diff --git a/services/notifications/notifications.go b/services/notifications/notifications.go
index 63c9dcde4be..5359ba2562d 100644
--- a/services/notifications/notifications.go
+++ b/services/notifications/notifications.go
@@ -223,7 +223,7 @@ func (self *Notifier) ProcessPing(ctx context.Context,
is_client_connected = self.notification_pool.IsClientConnected(client_id)
}
- return journal.PushRowsToArtifact(config_obj,
+ return journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", client_id).
Set("NotifyTarget", notify_target).
@@ -250,7 +250,8 @@ func (self *Notifier) CountConnectedClients() uint64 {
return self.notification_pool.Count()
}
-func (self *Notifier) NotifyListener(config_obj *config_proto.Config,
+func (self *Notifier) NotifyListener(
+ ctx context.Context, config_obj *config_proto.Config,
id, tag string) error {
journal, err := services.GetJournal(config_obj)
if err != nil {
@@ -259,7 +260,7 @@ func (self *Notifier) NotifyListener(config_obj *config_proto.Config,
// We need to send this ASAP so we do not use an async send.
notificationsSentCounter.Inc()
- return journal.PushRowsToArtifact(config_obj,
+ return journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("Tag", tag).
Set("Target", id)},
@@ -277,15 +278,15 @@ func (self *Notifier) NotifyDirectListener(client_id string) {
}
}
-func (self *Notifier) NotifyListenerAsync(config_obj *config_proto.Config,
- id, tag string) {
+func (self *Notifier) NotifyListenerAsync(
+ ctx context.Context, config_obj *config_proto.Config, id, tag string) {
journal, err := services.GetJournal(config_obj)
if err != nil {
return
}
notificationsSentCounter.Inc()
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("Tag", tag).
Set("Target", id),
@@ -371,7 +372,7 @@ func (self *Notifier) IsClientConnected(
self.mu.Unlock()
// Push request immediately for low latency.
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", client_id).
Set("NotifyTarget", id)},
diff --git a/services/repository.go b/services/repository.go
index fe2e59d29af..bbfc36cc64a 100644
--- a/services/repository.go
+++ b/services/repository.go
@@ -86,14 +86,15 @@ type Repository interface {
*artifacts_proto.Artifact, error)
// Get an artifact by name.
- Get(config_obj *config_proto.Config,
+ Get(ctx context.Context, config_obj *config_proto.Config,
name string) (*artifacts_proto.Artifact, bool)
- GetSource(config_obj *config_proto.Config,
+ GetSource(ctx context.Context, config_obj *config_proto.Config,
name string) (*artifacts_proto.ArtifactSource, bool)
// An optimization that avoids copying the entire artifact definition
- GetArtifactType(config_obj *config_proto.Config, artifact_name string) (string, error)
+ GetArtifactType(ctx context.Context, config_obj *config_proto.Config,
+ artifact_name string) (string, error)
// Remove a named artifact from the repository.
Del(name string)
@@ -134,12 +135,13 @@ type RepositoryManager interface {
BuildScopeFromScratch(builder ScopeBuilder) vfilter.Scope
// Store the file to the repository. It will be stored in the datastore as well.
- SetArtifactFile(config_obj *config_proto.Config, principal string,
+ SetArtifactFile(
+ ctx context.Context, config_obj *config_proto.Config, principal string,
data, required_prefix string) (*artifacts_proto.Artifact, error)
// Delete the file from the global repository and the data store.
- DeleteArtifactFile(config_obj *config_proto.Config,
- principal, name string) error
+ DeleteArtifactFile(ctx context.Context,
+ config_obj *config_proto.Config, principal, name string) error
}
type MockablePlugin interface {
diff --git a/services/repository/manager.go b/services/repository/manager.go
index 921261382be..71e23e70841 100644
--- a/services/repository/manager.go
+++ b/services/repository/manager.go
@@ -134,7 +134,8 @@ func (self *RepositoryManager) SetGlobalRepositoryForTests(
}
func (self *RepositoryManager) SetArtifactFile(
- config_obj *config_proto.Config, principal, definition, required_prefix string) (
+ ctx context.Context, config_obj *config_proto.Config,
+ principal, definition, required_prefix string) (
*artifacts_proto.Artifact, error) {
// Use regexes to force the artifact into the correct prefix.
@@ -201,7 +202,7 @@ func (self *RepositoryManager) SetArtifactFile(
return nil, err
}
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("setter", principal).
@@ -220,14 +221,15 @@ func (self *RepositoryManager) SetParent(
}
func (self *RepositoryManager) DeleteArtifactFile(
- config_obj *config_proto.Config, principal, name string) error {
+ ctx context.Context, config_obj *config_proto.Config,
+ principal, name string) error {
global_repository, err := self.GetGlobalRepository(config_obj)
if err != nil {
return err
}
// If not there nothing to do...
- _, pres := global_repository.Get(config_obj, name)
+ _, pres := global_repository.Get(ctx, config_obj, name)
if !pres {
return nil
}
@@ -241,7 +243,7 @@ func (self *RepositoryManager) DeleteArtifactFile(
return err
}
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{
ordereddict.NewDict().
Set("setter", principal).
@@ -402,7 +404,7 @@ func LoadBuiltInArtifacts(ctx context.Context,
return
default:
- _, pres := grepository.Get(config_obj, name)
+ _, pres := grepository.Get(ctx, config_obj, name)
if !pres {
grepository.Del(name)
}
diff --git a/services/repository/manager_test.go b/services/repository/manager_test.go
index 22bdc49b887..33f8985fb8c 100644
--- a/services/repository/manager_test.go
+++ b/services/repository/manager_test.go
@@ -47,7 +47,7 @@ func (self *ManagerTestSuite) TestSetArtifact() {
assert.NoError(self.T(), err)
// Coerce artifact into a prefix.
- artifact, err := manager.SetArtifactFile(self.ConfigObj, "User", `
+ artifact, err := manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: TestArtifact
`, "Custom." /* required_prefix */)
@@ -63,7 +63,7 @@ name: TestArtifact
assert.Contains(self.T(), string(data), "Custom.TestArtifact")
// Make sure a creation event was written
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx,
self.ConfigObj, "", "", "Server.Internal.ArtifactModification")
assert.NoError(self.T(), err)
path_manager.Clock = clock
@@ -113,7 +113,8 @@ func (self *ManagerTestSuite) TestSetArtifactDetectedByMinion() {
fmt.Sprintf("%p", master_manager))
// Coerce artifact into a prefix.
- artifact, err := master_manager.SetArtifactFile(self.ConfigObj, "User", `
+ artifact, err := master_manager.SetArtifactFile(
+ self.Ctx, self.ConfigObj, "User", `
name: TestArtifact
`, "")
@@ -125,17 +126,17 @@ name: TestArtifact
// Wait until the minion knows about the new artifact.
vtesting.WaitUntil(5*time.Second, self.T(), func() bool {
- _, ok := minion_repository.Get(minion_config, artifact.Name)
+ _, ok := minion_repository.Get(self.Ctx, minion_config, artifact.Name)
return ok
})
// Now delete the artifact.
- err = master_manager.DeleteArtifactFile(self.ConfigObj, "User", "TestArtifact")
+ err = master_manager.DeleteArtifactFile(self.Ctx, self.ConfigObj, "User", "TestArtifact")
assert.NoError(self.T(), err)
// Wait until the minion removes it from its repository.
vtesting.WaitUntil(5*time.Second, self.T(), func() bool {
- _, found := minion_repository.Get(minion_config, artifact.Name)
+ _, found := minion_repository.Get(self.Ctx, minion_config, artifact.Name)
return !found
})
}
@@ -147,7 +148,7 @@ func (self *ManagerTestSuite) TestSetArtifactWithExistingPrefix() {
assert.NoError(self.T(), err)
// Coerce artifact into a prefix.
- artifact, err := manager.SetArtifactFile(self.ConfigObj, "User", `
+ artifact, err := manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.TestArtifact
`, "Custom." /* required_prefix */)
@@ -168,7 +169,7 @@ func (self *ManagerTestSuite) TestSetArtifactWithInvalidArtifact() {
assert.NoError(self.T(), err)
// Invalid YAML
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
nameXXXXX: Custom.TestArtifact
`, "Custom." /* required_prefix */)
@@ -176,7 +177,7 @@ nameXXXXX: Custom.TestArtifact
assert.Contains(self.T(), err.Error(), "field nameXXXXX not found in type")
// Valid YAML but invalid VQL
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.TestArtifact
sources:
- query: "SELECT 1"
@@ -191,34 +192,34 @@ func (self *ManagerTestSuite) TestSetArtifactOverrideBuiltIn() {
assert.NoError(self.T(), err)
// Try to override an existing artifact
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Generic.Client.Info
`, "" /* required_prefix */)
assert.Error(self.T(), err)
assert.Contains(self.T(), err.Error(), "Unable to override built in artifact")
// Set Custom artifact
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.Generic.Client.Info
`, "" /* required_prefix */)
assert.NoError(self.T(), err)
// Override it again
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.Generic.Client.Info
`, "" /* required_prefix */)
assert.NoError(self.T(), err)
// Set Custom artifact with built_in in definition (this is a
// private field which should be ignored).
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.Generic.Client.Info
built_in: true
`, "" /* required_prefix */)
assert.NoError(self.T(), err)
// Override it again
- _, err = manager.SetArtifactFile(self.ConfigObj, "User", `
+ _, err = manager.SetArtifactFile(self.Ctx, self.ConfigObj, "User", `
name: Custom.Generic.Client.Info
built_in: true
`, "" /* required_prefix */)
diff --git a/services/repository/plugin.go b/services/repository/plugin.go
index 452766047fb..685141da732 100644
--- a/services/repository/plugin.go
+++ b/services/repository/plugin.go
@@ -92,7 +92,7 @@ func (self *ArtifactRepositoryPlugin) Call(
artifact_name_with_source := artifact_name + "/" + source
- artifact, pres = self.repository.Get(
+ artifact, pres = self.repository.Get(ctx,
self.config_obj, artifact_name_with_source)
if !pres {
scope.Log("Source %v not found in artifact %v",
@@ -104,7 +104,8 @@ func (self *ArtifactRepositoryPlugin) Call(
} else {
- artifact, pres = self.repository.Get(self.config_obj, artifact_name)
+ artifact, pres = self.repository.Get(
+ ctx, self.config_obj, artifact_name)
if !pres {
scope.Log("Artifact %v not found", artifact_name)
return
diff --git a/services/repository/plugin_test.go b/services/repository/plugin_test.go
index 8ce6a7599e9..10a63dbadc7 100644
--- a/services/repository/plugin_test.go
+++ b/services/repository/plugin_test.go
@@ -68,7 +68,7 @@ func (self *PluginTestSuite) TestArtifactsSyntax() {
assert.NoError(self.T(), err)
for _, artifact_name := range names {
- artifact, pres := repository.Get(ConfigObj, artifact_name)
+ artifact, pres := repository.Get(self.Ctx, ConfigObj, artifact_name)
assert.True(self.T(), pres)
if artifact != nil && !artifact.IsAlias {
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 72d7fbaebd5..c1309228ea7 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -59,6 +59,8 @@ type Repository struct {
parent_config_obj *config_proto.Config
}
+// A Parent repository is another repository we can delegate to if we
+// dont have the artifact definition we require.
func (self *Repository) SetParent(
parent services.Repository, parent_config_obj *config_proto.Config) {
self.mu.Lock()
@@ -361,8 +363,9 @@ func (self *Repository) LoadProto(artifact *artifacts_proto.Artifact, validate b
}
func (self *Repository) GetArtifactType(
- config_obj *config_proto.Config, artifact_name string) (string, error) {
- artifact, pres := self.Get(config_obj, artifact_name)
+ ctx context.Context, config_obj *config_proto.Config,
+ artifact_name string) (string, error) {
+ artifact, pres := self.Get(ctx, config_obj, artifact_name)
if !pres {
return "", fmt.Errorf("Artifact %s not known", artifact_name)
}
@@ -371,9 +374,10 @@ func (self *Repository) GetArtifactType(
}
func (self *Repository) GetSource(
- config_obj *config_proto.Config, name string) (*artifacts_proto.ArtifactSource, bool) {
+ ctx context.Context, config_obj *config_proto.Config,
+ name string) (*artifacts_proto.ArtifactSource, bool) {
artifact_name, source_name := paths.SplitFullSourceName(name)
- artifact, pres := self.Get(config_obj, artifact_name)
+ artifact, pres := self.Get(ctx, config_obj, artifact_name)
if !pres {
return nil, false
}
@@ -387,7 +391,8 @@ func (self *Repository) GetSource(
}
func (self *Repository) Get(
- config_obj *config_proto.Config, name string) (*artifacts_proto.Artifact, bool) {
+ ctx context.Context, config_obj *config_proto.Config,
+ name string) (*artifacts_proto.Artifact, bool) {
self.mu.Lock()
cached_artifact, pres := self.get(name)
if !pres {
@@ -395,7 +400,7 @@ func (self *Repository) Get(
// If we have a parent repository just get it from there.
if self.parent != nil {
- return self.parent.Get(self.parent_config_obj, name)
+ return self.parent.Get(ctx, self.parent_config_obj, name)
}
return nil, false
}
@@ -410,7 +415,7 @@ func (self *Repository) Get(
// Delay processing until we need it. This means loading
// artifacts is faster.
- err := compileArtifact(config_obj, result)
+ err := compileArtifact(ctx, config_obj, result)
if err != nil {
logger := logging.GetLogger(config_obj, &logging.GenericComponent)
logger.Error("While compiling artifact %v: %v", name, err)
@@ -542,8 +547,9 @@ func splitQueryToQueries(query string) ([]string, error) {
}
func compileArtifact(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
artifact *artifacts_proto.Artifact) error {
+
if artifact.Compiled {
return nil
}
@@ -560,7 +566,14 @@ func compileArtifact(
source.Queries = queries
}
}
+ artifact.Compiled = true
+
+ return updateTools(ctx, config_obj, artifact)
+}
+func updateTools(
+ ctx context.Context, config_obj *config_proto.Config,
+ artifact *artifacts_proto.Artifact) error {
// Make sure tools are all defined.
inventory, err := services.GetInventory(config_obj)
if err != nil {
@@ -568,15 +581,13 @@ func compileArtifact(
}
for _, tool := range artifact.Tools {
- err := inventory.AddTool(
- config_obj, tool,
+ tool_request := proto.Clone(tool).(*artifacts_proto.Tool)
+ tool_request.Artifact = artifact.Name
+ err := inventory.AddTool(ctx, config_obj, tool_request,
services.ToolOptions{Upgrade: true})
if err != nil {
return err
}
}
-
- artifact.Compiled = true
-
return nil
}
diff --git a/services/repository/repository_test.go b/services/repository/repository_test.go
index 8dc831ebb8f..402351950c4 100644
--- a/services/repository/repository_test.go
+++ b/services/repository/repository_test.go
@@ -59,7 +59,7 @@ func TestLoadingFromFilestore(t *testing.T) {
repository, err := manager.GetGlobalRepository(config_obj)
assert.NoError(t, err)
- artifact, pres := repository.Get(config_obj, "Custom.TestArtifact")
+ artifact, pres := repository.Get(ctx, config_obj, "Custom.TestArtifact")
assert.True(t, pres)
assert.Equal(t, artifact.Name, "Custom.TestArtifact")
diff --git a/services/sanity/fixtures/TestUpgradeTools.golden b/services/sanity/fixtures/TestUpgradeTools.golden
index 9b88e08ca88..6a7768a4f61 100644
--- a/services/sanity/fixtures/TestUpgradeTools.golden
+++ b/services/sanity/fixtures/TestUpgradeTools.golden
@@ -9,6 +9,7 @@
"url": "https://www.company.com"
},
{
+ "artifact": "TestArtifact",
"filename": "www.example2.com",
"filestore_path": "9a0dbc5804c7e06fc2e371a936bbe1d90b206aa9b8fbad7601f4a7f70fb596e1",
"name": "Tool2",
diff --git a/services/sanity/sanity.go b/services/sanity/sanity.go
index 74ecaef1491..212b6aa6507 100644
--- a/services/sanity/sanity.go
+++ b/services/sanity/sanity.go
@@ -247,7 +247,7 @@ func checkForServerUpgrade(
}
for _, name := range names {
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if !pres {
continue
}
@@ -265,7 +265,8 @@ func checkForServerUpgrade(
// If the existing tool definition was overridden
// by the admin do not alter it.
- tool, err := inventory.ProbeToolInfo(tool_definition.Name)
+ tool, err := inventory.ProbeToolInfo(
+ ctx, config_obj, tool_definition.Name)
if err == nil && tool.AdminOverride {
logger.Info("Skipping update> of tool %v> because an admin manually overrode its definition.",
tool_definition.Name)
@@ -284,7 +285,7 @@ func checkForServerUpgrade(
// when the tool is used next.
tool_definition.Hash = ""
- err = inventory.AddTool(
+ err = inventory.AddTool(ctx,
config_obj, tool_definition,
services.ToolOptions{
Upgrade: true,
diff --git a/services/sanity/sanity_test.go b/services/sanity/sanity_test.go
index 17a61938876..c1eb6b8d2be 100644
--- a/services/sanity/sanity_test.go
+++ b/services/sanity/sanity_test.go
@@ -60,7 +60,8 @@ func (self *ServicesTestSuite) TestUpgradeTools() {
Name: "Tool1",
Url: "https://www.company.com",
}
- err = inventory_service.AddTool(self.ConfigObj, tool_definition,
+ ctx := self.Ctx
+ err = inventory_service.AddTool(ctx, self.ConfigObj, tool_definition,
services.ToolOptions{
// This flag signifies that an admin explicitly set
// this tool. We never overwrite an admin's setting.
diff --git a/services/server_artifacts/api.go b/services/server_artifacts/api.go
index f47c064f1c4..0bdf500b921 100644
--- a/services/server_artifacts/api.go
+++ b/services/server_artifacts/api.go
@@ -1,6 +1,7 @@
package server_artifacts
import (
+ "context"
"io"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
@@ -38,9 +39,9 @@ type CollectionContextManager interface {
// Cancel all the queries in this collection immediately and wait
// for them to complete
- Cancel(princiapl string)
+ Cancel(ctx context.Context, princiapl string)
- Close()
+ Close(ctx context.Context)
ChargeBytes(bytes int64)
}
diff --git a/services/server_artifacts/collection_context.go b/services/server_artifacts/collection_context.go
index 13cc11232fd..93b4970e2e3 100644
--- a/services/server_artifacts/collection_context.go
+++ b/services/server_artifacts/collection_context.go
@@ -253,7 +253,7 @@ func (self *contextManager) Save() error {
self.ctx, self.config_obj, context)
}
-func (self *contextManager) Cancel(principal string) {
+func (self *contextManager) Cancel(ctx context.Context, principal string) {
self.mu.Lock()
for _, query_ctx := range self.query_contexts {
query_ctx.UpdateStatus(func(s *crypto_proto.VeloStatus) {
@@ -266,17 +266,17 @@ func (self *contextManager) Cancel(principal string) {
self.cancel()
self.wg.Wait()
- self.maybeSendCompletionMessage()
+ self.maybeSendCompletionMessage(ctx)
}
-func (self *contextManager) Close() {
+func (self *contextManager) Close(ctx context.Context) {
self.wg.Wait()
- self.maybeSendCompletionMessage()
+ self.maybeSendCompletionMessage(ctx)
}
// Called when each query is completed. Will send the message once for
// the entire flow completion.
-func (self *contextManager) maybeSendCompletionMessage() {
+func (self *contextManager) maybeSendCompletionMessage(ctx context.Context) {
flow_context := self.GetContext()
if flow_context.State == flows_proto.ArtifactCollectorContext_RUNNING {
return
@@ -292,7 +292,7 @@ func (self *contextManager) maybeSendCompletionMessage() {
if err != nil {
return
}
- journal.PushRowsToArtifact(self.config_obj,
+ journal.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{row},
"System.Flow.Completion", "server", self.session_id,
)
diff --git a/services/server_artifacts/server_artifacts.go b/services/server_artifacts/server_artifacts.go
index 228f80cdc0e..3b498fd6ae7 100644
--- a/services/server_artifacts/server_artifacts.go
+++ b/services/server_artifacts/server_artifacts.go
@@ -76,7 +76,7 @@ func (self *ServerArtifactsRunner) process(
if req.Cancel != nil {
// This collection is now done, cancel it.
- self.Cancel(session_id, req.Cancel.Principal)
+ self.Cancel(ctx, session_id, req.Cancel.Principal)
return nil
}
@@ -94,7 +94,7 @@ func (self *ServerArtifactsRunner) process(
defer cancel()
defer collection_context.Save()
- self.ProcessTask(config_obj,
+ self.ProcessTask(sub_ctx, config_obj,
req.SessionId, collection_context, req.FlowRequest)
}()
}
@@ -103,13 +103,14 @@ func (self *ServerArtifactsRunner) process(
return nil
}
-func (self *ServerArtifactsRunner) Cancel(flow_id, principal string) {
+func (self *ServerArtifactsRunner) Cancel(
+ ctx context.Context, flow_id, principal string) {
self.mu.Lock()
defer self.mu.Unlock()
context_manager, pres := self.in_flight_collections[flow_id]
if pres {
- context_manager.Cancel(principal)
+ context_manager.Cancel(ctx, principal)
delete(self.in_flight_collections, flow_id)
}
}
@@ -119,7 +120,7 @@ func (self *ServerArtifactsRunner) Cancel(flow_id, principal string) {
// compiler will decide how to structure the artifact into multiple
// VQLClientActions (e.g. by considering precondition clauses).
func (self *ServerArtifactsRunner) ProcessTask(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
session_id string,
collection_context CollectionContextManager,
req *crypto_proto.FlowRequest) error {
@@ -131,7 +132,7 @@ func (self *ServerArtifactsRunner) ProcessTask(
// Wait here for all the queries to exit then remove them from the
// in_flight_collections map.
defer func() {
- collection_context.Close()
+ collection_context.Close(ctx)
self.mu.Lock()
delete(self.in_flight_collections, session_id)
diff --git a/services/server_artifacts/server_artifacts_test.go b/services/server_artifacts/server_artifacts_test.go
index e3bbe25f4e5..df7aefd04bf 100644
--- a/services/server_artifacts/server_artifacts_test.go
+++ b/services/server_artifacts/server_artifacts_test.go
@@ -59,6 +59,7 @@ func (self *ServerArtifactsTestSuite) LoadArtifacts(definition string) services.
func (self *ServerArtifactsTestSuite) ScheduleAndWait(
name, user, flow_id string) *api_proto.FlowDetails {
+ ctx := self.Ctx
manager, _ := services.GetRepositoryManager(self.ConfigObj)
repository, _ := manager.GetGlobalRepository(self.ConfigObj)
@@ -100,7 +101,7 @@ func (self *ServerArtifactsTestSuite) ScheduleAndWait(
notifier, err := services.GetNotifier(self.ConfigObj)
assert.NoError(self.T(), err)
- err = notifier.NotifyListener(self.ConfigObj, "server", "")
+ err = notifier.NotifyListener(ctx, self.ConfigObj, "server", "")
assert.NoError(self.T(), err)
})
assert.NoError(self.T(), err)
diff --git a/services/server_artifacts/server_uploader.go b/services/server_artifacts/server_uploader.go
index 45722833c04..6d23ce934f2 100644
--- a/services/server_artifacts/server_uploader.go
+++ b/services/server_artifacts/server_uploader.go
@@ -99,7 +99,7 @@ func (self *ServerUploader) Upload(
Set("Size", result.Size).
Set("UploadedSize", result.Size)
- err = journal.PushRowsToArtifact(self.config_obj,
+ err = journal.PushRowsToArtifact(ctx, self.config_obj,
[]*ordereddict.Dict{row},
"System.Upload.Completion",
"server", self.session_id,
diff --git a/services/server_monitoring/server_monitoring.go b/services/server_monitoring/server_monitoring.go
index ad247c13715..f159faf0cb1 100644
--- a/services/server_monitoring/server_monitoring.go
+++ b/services/server_monitoring/server_monitoring.go
@@ -312,7 +312,7 @@ func (self *EventTable) RunQuery(
}
artifact_name := getArtifactName(vql_request)
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, "", "", artifact_name)
if err != nil {
return err
@@ -321,7 +321,7 @@ func (self *EventTable) RunQuery(
path_manager.Clock = self.clock
// We write the logs to special files.
- log_path_manager, err := artifacts.NewArtifactLogPathManager(
+ log_path_manager, err := artifacts.NewArtifactLogPathManager(ctx,
config_obj, "server", "", artifact_name)
if err != nil {
return err
diff --git a/services/server_monitoring/server_monitoring_test.go b/services/server_monitoring/server_monitoring_test.go
index acc6d23340b..0c57425b71e 100644
--- a/services/server_monitoring/server_monitoring_test.go
+++ b/services/server_monitoring/server_monitoring_test.go
@@ -327,7 +327,9 @@ sources:
// Now we update the artifact definition and the monitoring table
// should magically be updated and the new artifact run instead.
- _, err = manager.SetArtifactFile(self.ConfigObj, "user", `
+ ctx := self.Ctx
+ _, err = manager.SetArtifactFile(
+ ctx, self.ConfigObj, "user", `
name: TestArtifact
type: SERVER_EVENT
parameters:
diff --git a/services/vfs_service/vfs_service.go b/services/vfs_service/vfs_service.go
index 9fd04f4aa56..b44f9d2a405 100644
--- a/services/vfs_service/vfs_service.go
+++ b/services/vfs_service/vfs_service.go
@@ -89,7 +89,7 @@ func (self *VFSService) ProcessDownloadFile(
flow_path_manager := paths.NewFlowPathManager(client_id, flow_id)
client_path_manager := paths.NewClientPathManager(client_id)
- artifact_path_manager, err := artifacts.NewArtifactPathManager(config_obj,
+ artifact_path_manager, err := artifacts.NewArtifactPathManager(ctx, config_obj,
client_id, flow_id, "System.VFS.DownloadFile")
if err != nil {
logger.Error("Unable to read artifact: %v", err)
diff --git a/services/vfs_service/vfs_service_test.go b/services/vfs_service/vfs_service_test.go
index 1d9b31127e9..0b7347f9041 100644
--- a/services/vfs_service/vfs_service_test.go
+++ b/services/vfs_service/vfs_service_test.go
@@ -70,11 +70,11 @@ func (self *VFSServiceTestSuite) EmulateCollection(
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- journal.PushRowsToArtifact(self.ConfigObj, rows,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj, rows,
artifact, self.client_id, self.flow_id)
// Emulate a flow completion message coming from the flow processor.
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", self.client_id).
Set("FlowId", self.flow_id).
@@ -100,14 +100,14 @@ func (self *VFSServiceTestSuite) EmulateCollectionWithVFSLs(
journal, err := services.GetJournal(self.ConfigObj)
assert.NoError(self.T(), err)
- journal.PushRowsToArtifact(self.ConfigObj, rows,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj, rows,
artifact+"/Listing", self.client_id, self.flow_id)
- journal.PushRowsToArtifact(self.ConfigObj, stats,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj, stats,
artifact+"/Stats", self.client_id, self.flow_id)
// Emulate a flow completion message coming from the flow processor.
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", self.client_id).
Set("FlowId", self.flow_id).
@@ -202,7 +202,7 @@ func (self *VFSServiceTestSuite) TestVFSListDirectoryEmpty() {
// Emulate a flow completion message coming from the flow processor.
artifact := "System.VFS.ListDirectory"
- journal.PushRowsToArtifact(self.ConfigObj,
+ journal.PushRowsToArtifact(self.Ctx, self.ConfigObj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", self.client_id).
Set("FlowId", self.flow_id).
diff --git a/vql/server/clients/delete.go b/vql/server/clients/delete.go
index 99ae9d1ceaf..1d3f4025806 100644
--- a/vql/server/clients/delete.go
+++ b/vql/server/clients/delete.go
@@ -161,7 +161,7 @@ func (self DeleteClientPlugin) Call(ctx context.Context,
// it is already up.
notifier, err := services.GetNotifier(config_obj)
if err == nil {
- err = notifier.NotifyListener(
+ err = notifier.NotifyListener(ctx,
config_obj, arg.ClientId, "DeleteClient")
if err != nil {
scope.Log("client_delete: %s", err)
@@ -236,7 +236,7 @@ func reallyDeleteClient(ctx context.Context,
"org_id": config_obj.OrgId,
})
- return journal.PushRowsToArtifact(config_obj,
+ return journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("ClientId", arg.ClientId).
Set("OrgId", config_obj.OrgId).
diff --git a/vql/server/downloads/downloads.go b/vql/server/downloads/downloads.go
index e1c172e07f6..2be27d69c78 100644
--- a/vql/server/downloads/downloads.go
+++ b/vql/server/downloads/downloads.go
@@ -318,7 +318,7 @@ func downloadFlowToZip(
// Copy artifact results
for _, name := range flow_details.Context.ArtifactsWithResults {
- artifact_path_manager, err := artifacts.NewArtifactPathManager(
+ artifact_path_manager, err := artifacts.NewArtifactPathManager(ctx,
config_obj, client_id, flow_id, name)
if err != nil {
continue
diff --git a/vql/server/events.go b/vql/server/events.go
index bb8aa3410e6..8a091ea6a3a 100644
--- a/vql/server/events.go
+++ b/vql/server/events.go
@@ -54,7 +54,7 @@ func (self *SendEventFunction) Call(ctx context.Context,
// We only allow to publish server events - client events come
// from the client only and not from VQL.
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{arg.Row}, arg.Artifact, "server", "")
if err != nil {
scope.Log("send_event: %v", err)
diff --git a/vql/server/flows/create.go b/vql/server/flows/create.go
index e2a68363cdf..ed072f72d16 100644
--- a/vql/server/flows/create.go
+++ b/vql/server/flows/create.go
@@ -148,7 +148,7 @@ func (self *ScheduleCollectionFunction) Call(ctx context.Context,
arg.Spec = spec
}
- err = collector.AddSpecProtobuf(config_obj, repository, scope,
+ err = collector.AddSpecProtobuf(ctx, config_obj, repository, scope,
arg.Spec, request)
if err != nil {
scope.Log("collect_client: %v", err)
@@ -172,7 +172,7 @@ func (self *ScheduleCollectionFunction) Call(ctx context.Context,
// Notify the client about it.
notifier, err := services.GetNotifier(config_obj)
if err == nil {
- notifier.NotifyListener(
+ notifier.NotifyListener(ctx,
config_obj, arg.ClientId, "collect_client")
}
})
diff --git a/vql/server/flows/monitoring.go b/vql/server/flows/monitoring.go
index 38e9e562ab9..b57813aafd2 100644
--- a/vql/server/flows/monitoring.go
+++ b/vql/server/flows/monitoring.go
@@ -76,7 +76,7 @@ func (self MonitoringPlugin) Call(
arg.Source = ""
}
- path_manager, err := artifact_paths.NewArtifactPathManager(
+ path_manager, err := artifact_paths.NewArtifactPathManager(ctx,
config_obj, arg.ClientId, arg.FlowId, arg.Artifact)
if err != nil {
scope.Log("monitoring: %v", err)
@@ -183,7 +183,7 @@ func (self WatchMonitoringPlugin) Call(
return
}
- mode, err := artifact_paths.GetArtifactMode(
+ mode, err := artifact_paths.GetArtifactMode(ctx,
config_obj, arg.Artifact)
if err != nil {
scope.Log("Artifact %s not known", arg.Artifact)
diff --git a/vql/server/flows/parallel_test.go b/vql/server/flows/parallel_test.go
index 35c1889c73a..5d57e675ed9 100644
--- a/vql/server/flows/parallel_test.go
+++ b/vql/server/flows/parallel_test.go
@@ -57,7 +57,7 @@ func (self *TestSuite) TestArtifactSource() {
file_store_factory := file_store.GetFileStore(self.ConfigObj)
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx,
self.ConfigObj, self.client_id, self.flow_id,
"Test.Artifact")
assert.NoError(self.T(), err)
@@ -174,7 +174,7 @@ func (self *TestSuite) TestHuntsSource() {
Set("_ts", 0).
Set("Timestamp", 0))
- path_manager, err := artifacts.NewArtifactPathManager(
+ path_manager, err := artifacts.NewArtifactPathManager(self.Ctx,
self.ConfigObj, client_id, flow_id, "Test.Artifact")
assert.NoError(self.T(), err)
diff --git a/vql/server/flows/results.go b/vql/server/flows/results.go
index c7e5aa25567..9a13159aca4 100644
--- a/vql/server/flows/results.go
+++ b/vql/server/flows/results.go
@@ -134,7 +134,7 @@ func (self SourcePlugin) Call(
// Event artifacts just proxy for the monitoring plugin.
if arg.NotebookCellId == "" && arg.Artifact != "" {
- ok, _ := isArtifactEvent(config_obj, arg)
+ ok, _ := isArtifactEvent(ctx, config_obj, arg)
if ok {
// Just delegate directly to the monitoring plugin.
return MonitoringPlugin{}.Call(ctx, scope, args)
@@ -189,7 +189,7 @@ func (self SourcePlugin) Info(
// Figure out if the artifact is an event artifact based on its
// definition.
func isArtifactEvent(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
arg *SourcePluginArgs) (bool, error) {
manager, err := services.GetRepositoryManager(config_obj)
@@ -202,7 +202,7 @@ func isArtifactEvent(
return false, err
}
- artifact_definition, pres := repository.Get(config_obj, arg.Artifact)
+ artifact_definition, pres := repository.Get(ctx, config_obj, arg.Artifact)
if !pres {
return false, fmt.Errorf("Artifact %v not known", arg.Artifact)
}
@@ -251,7 +251,7 @@ func getResultSetReader(
arg.Source = ""
}
- is_event, err := isArtifactEvent(config_obj, arg)
+ is_event, err := isArtifactEvent(ctx, config_obj, arg)
if err != nil {
return nil, err
}
@@ -268,7 +268,7 @@ func getResultSetReader(
"be specified for non event artifacts.")
}
- path_manager, err := artifact_paths.NewArtifactPathManager(
+ path_manager, err := artifact_paths.NewArtifactPathManager(ctx,
config_obj, arg.ClientId, arg.FlowId, arg.Artifact)
if err != nil {
return nil, err
@@ -409,7 +409,7 @@ func (self FlowResultsPlugin) Call(
arg.Source = ""
}
- path_manager, err := artifact_paths.NewArtifactPathManager(
+ path_manager, err := artifact_paths.NewArtifactPathManager(ctx,
config_obj, arg.ClientId, arg.FlowId, arg.Artifact)
if err != nil {
scope.Log("source: %v", err)
diff --git a/vql/server/hunts/create.go b/vql/server/hunts/create.go
index d1959f66472..1331417bc87 100644
--- a/vql/server/hunts/create.go
+++ b/vql/server/hunts/create.go
@@ -135,7 +135,7 @@ func (self *ScheduleHuntFunction) Call(ctx context.Context,
}
principal := vql_subsystem.GetPrincipal(scope)
- err = collector.AddSpecProtobuf(config_obj, repository, scope,
+ err = collector.AddSpecProtobuf(ctx, config_obj, repository, scope,
arg.Spec, request)
if err != nil {
scope.Log("hunt: %v", err)
@@ -312,7 +312,7 @@ func (self *AddToHuntFunction) Call(ctx context.Context,
// Send this
if arg.FlowId != "" {
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", arg.HuntId).
Set("mutation", &api_proto.HuntMutation{
@@ -324,7 +324,7 @@ func (self *AddToHuntFunction) Call(ctx context.Context,
})},
"Server.Internal.HuntModification", arg.ClientId, "")
} else {
- err = journal.PushRowsToArtifact(config_obj,
+ err = journal.PushRowsToArtifact(ctx, config_obj,
[]*ordereddict.Dict{ordereddict.NewDict().
Set("HuntId", arg.HuntId).
Set("ClientId", arg.ClientId).
diff --git a/vql/server/hunts/delete.go b/vql/server/hunts/delete.go
index 2ce48688f1c..73d87fe7bb8 100644
--- a/vql/server/hunts/delete.go
+++ b/vql/server/hunts/delete.go
@@ -108,7 +108,7 @@ func (self DeleteHuntPlugin) Call(ctx context.Context,
return
}
- journal.PushRowsToArtifactAsync(config_obj,
+ journal.PushRowsToArtifactAsync(ctx, config_obj,
ordereddict.NewDict().
Set("hunt_id", arg.HuntId).
Set("mutation", mutation),
diff --git a/vql/server/hunts/hunts.go b/vql/server/hunts/hunts.go
index 301a88bf4e1..c6ad04b180d 100644
--- a/vql/server/hunts/hunts.go
+++ b/vql/server/hunts/hunts.go
@@ -178,7 +178,7 @@ func (self HuntResultsPlugin) Call(
return
}
- hunt_dispatcher.FindCollectedArtifacts(config_obj, hunt_obj)
+ hunt_dispatcher.FindCollectedArtifacts(ctx, config_obj, hunt_obj)
if len(hunt_obj.Artifacts) == 0 {
scope.Log("hunt_results: no artifacts in hunt")
return
@@ -200,7 +200,7 @@ func (self HuntResultsPlugin) Call(
}
repo, err := manager.GetGlobalRepository(config_obj)
if err == nil {
- artifact_def, ok := repo.Get(config_obj, arg.Artifact)
+ artifact_def, ok := repo.Get(ctx, config_obj, arg.Artifact)
if ok {
for _, source := range artifact_def.Sources {
if source.Name != "" {
@@ -238,7 +238,7 @@ func (self HuntResultsPlugin) Call(
// Read individual flow's results.
path_manager, err := artifact_paths.NewArtifactPathManager(
- config_obj,
+ ctx, config_obj,
flow_details.Context.ClientId,
flow_details.Context.SessionId,
arg.Artifact)
diff --git a/vql/server/inventory.go b/vql/server/inventory.go
index 4d88ce57d04..d8bba6d8869 100644
--- a/vql/server/inventory.go
+++ b/vql/server/inventory.go
@@ -110,7 +110,7 @@ func (self *InventoryAddFunction) Call(ctx context.Context,
return vfilter.Null{}
}
- err = inventory.AddTool(
+ err = inventory.AddTool(ctx,
config_obj, tool, services.ToolOptions{
AdminOverride: true,
})
diff --git a/vql/server/monitoring/add_monitoring.go b/vql/server/monitoring/add_monitoring.go
index 92e529f5391..90e20facb78 100644
--- a/vql/server/monitoring/add_monitoring.go
+++ b/vql/server/monitoring/add_monitoring.go
@@ -58,7 +58,7 @@ func (self AddClientMonitoringFunction) Call(
return vfilter.Null{}
}
- artifact, pres := repository.Get(config_obj, arg.Artifact)
+ artifact, pres := repository.Get(ctx, config_obj, arg.Artifact)
if !pres {
scope.Log("add_client_monitoring: artifact %v not found", arg.Artifact)
return vfilter.Null{}
@@ -221,7 +221,7 @@ func (self AddServerMonitoringFunction) Call(
return vfilter.Null{}
}
- artifact, pres := repository.Get(config_obj, arg.Artifact)
+ artifact, pres := repository.Get(ctx, config_obj, arg.Artifact)
if !pres {
scope.Log("add_server_monitoring: artifact %v not found", arg.Artifact)
return vfilter.Null{}
diff --git a/vql/server/repository.go b/vql/server/repository.go
index 69ee393341b..9353faee006 100644
--- a/vql/server/repository.go
+++ b/vql/server/repository.go
@@ -79,7 +79,7 @@ func (self *ArtifactSetFunction) Call(ctx context.Context,
principal := vql_subsystem.GetPrincipal(scope)
- definition, err = manager.SetArtifactFile(
+ definition, err = manager.SetArtifactFile(ctx,
config_obj, principal, arg.Definition, arg.Prefix)
if err != nil {
scope.Log("artifact_set: %s", err)
@@ -133,7 +133,7 @@ func (self *ArtifactDeleteFunction) Call(ctx context.Context,
return vfilter.Null{}
}
- definition, pres := global_repository.Get(config_obj, arg.Name)
+ definition, pres := global_repository.Get(ctx, config_obj, arg.Name)
if !pres {
scope.Log("artifact_delete: Artifact '%v' not found", arg.Name)
return vfilter.Null{}
@@ -161,7 +161,7 @@ func (self *ArtifactDeleteFunction) Call(ctx context.Context,
}
principal := vql_subsystem.GetPrincipal(scope)
- err = manager.DeleteArtifactFile(config_obj, principal, arg.Name)
+ err = manager.DeleteArtifactFile(ctx, config_obj, principal, arg.Name)
if err != nil {
scope.Log("artifact_delete: %s", err)
return vfilter.Null{}
@@ -233,7 +233,7 @@ func (self ArtifactsPlugin) Call(
return
}
for _, name := range names {
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if pres {
select {
case <-ctx.Done():
@@ -247,7 +247,7 @@ func (self ArtifactsPlugin) Call(
seen := make(map[string]*artifacts_proto.Artifact)
for _, name := range arg.Names {
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if pres {
seen[artifact.Name] = artifact
}
@@ -259,7 +259,7 @@ func (self ArtifactsPlugin) Call(
return
}
- deps, err := launcher.GetDependentArtifacts(
+ deps, err := launcher.GetDependentArtifacts(ctx,
config_obj, repository, arg.Names)
if err != nil {
scope.Log("artifact_definitions: %v", err)
@@ -270,7 +270,7 @@ func (self ArtifactsPlugin) Call(
if name == "" {
continue
}
- artifact, pres := repository.Get(config_obj, name)
+ artifact, pres := repository.Get(ctx, config_obj, name)
if !pres {
scope.Log("artifact_definitions: artifact %v not known", name)
continue
diff --git a/vql/tools/collector/collector.go b/vql/tools/collector/collector.go
index 72db2796718..2e101342434 100644
--- a/vql/tools/collector/collector.go
+++ b/vql/tools/collector/collector.go
@@ -82,7 +82,7 @@ func (self CollectPlugin) Call(
output_chan, scope)
defer collection_manager.Close()
- request, err := self.configureCollection(collection_manager, arg)
+ request, err := self.configureCollection(ctx, collection_manager, arg)
if err != nil {
scope.Log("collect: %v", err)
return
@@ -101,7 +101,7 @@ func (self CollectPlugin) Call(
// Configures the collection manager with the provided args.
func (self CollectPlugin) configureCollection(
- manager *collectionManager, arg *CollectPluginArgs) (
+ ctx context.Context, manager *collectionManager, arg *CollectPluginArgs) (
*flows_proto.ArtifactCollectorArgs, error) {
format, err := reporting.GetContainerFormat(arg.Format)
@@ -150,7 +150,7 @@ func (self CollectPlugin) configureCollection(
// Compile the request into vql requests protobuf ready for
// acquisition.
- return getArtifactCollectorArgs(
+ return getArtifactCollectorArgs(ctx,
manager.config_obj, manager.repository, manager.scope, arg)
}
@@ -166,7 +166,7 @@ func (self CollectPlugin) Info(scope vfilter.Scope, type_map *vfilter.TypeMap) *
// Parse the plugin arg into an artifact collector arg that can be
// compiled into VQL requests
func getArtifactCollectorArgs(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
repository services.Repository,
scope vfilter.Scope,
arg *CollectPluginArgs) (*flows_proto.ArtifactCollectorArgs, error) {
@@ -175,7 +175,8 @@ func getArtifactCollectorArgs(
Artifacts: arg.Artifacts,
}
- err := AddSpecProtobuf(config_obj, repository, scope, arg.Args, request)
+ err := AddSpecProtobuf(ctx, config_obj,
+ repository, scope, arg.Args, request)
if err != nil {
return nil, err
}
@@ -216,7 +217,7 @@ func convertToArtifactSpecs(spec vfilter.Any) (*ordereddict.Dict, error) {
// artifact parameters are always strings, encoded according to the
// parameter type.
func AddSpecProtobuf(
- config_obj *config_proto.Config,
+ ctx context.Context, config_obj *config_proto.Config,
repository services.Repository,
scope vfilter.Scope, spec vfilter.Any,
request *flows_proto.ArtifactCollectorArgs) error {
@@ -232,7 +233,7 @@ func AddSpecProtobuf(
}
for _, name := range scope.GetMembers(spec) {
- artifact_definitions, pres := repository.Get(config_obj, name)
+ artifact_definitions, pres := repository.Get(ctx, config_obj, name)
if !pres {
// Artifact not known
return fmt.Errorf(`Parameter 'args' refers to an unknown artifact (%v). The 'args' parameter should be of the form {"Custom.Artifact.Name":{"arg":"value"}}`, name)
diff --git a/vql/tools/collector/collector_manager.go b/vql/tools/collector/collector_manager.go
index 3f07052941f..4b9e996e88c 100644
--- a/vql/tools/collector/collector_manager.go
+++ b/vql/tools/collector/collector_manager.go
@@ -425,7 +425,7 @@ func newCollectionManager(
ctx: subctx,
cancel: cancel,
config_obj: config_obj,
- collection_context: flows.NewCollectionContext(config_obj),
+ collection_context: flows.NewCollectionContext(ctx, config_obj),
output_chan: output_chan,
scope: scope,
}