Skip to content

Commit

Permalink
feat: add falcon_detection_details datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
anasmuhmd committed Oct 6, 2024
1 parent d322ab5 commit 0aedbc0
Show file tree
Hide file tree
Showing 8 changed files with 648 additions and 1 deletion.
1 change: 1 addition & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ packages:
interfaces:
Client:
CspmRegistrationClient:
DetectsClient:
github.com/blackstork-io/fabric/plugin/resolver:
config:
inpackage: true
Expand Down
93 changes: 93 additions & 0 deletions docs/plugins/crowdstrike/data-sources/falcon_detection_details.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: "`falcon_detection_details` data source"
plugin:
name: blackstork/crowdstrike
description: "The `falcon_detection_details` data source fetches detection details from Falcon API"
tags: []
version: "v0.4.2"
source_github: "https://github.com/blackstork-io/fabric/tree/main/internal/crowdstrike/"
resource:
type: data-source
type: docs
---

{{< breadcrumbs 2 >}}

{{< plugin-resource-header "blackstork/crowdstrike" "crowdstrike" "v0.4.2" "falcon_detection_details" "data source" >}}

## Description
The `falcon_detection_details` data source fetches detection details from Falcon API.

## Installation

To use `falcon_detection_details` data source, you must install the plugin `blackstork/crowdstrike`.

To install the plugin, add the full plugin name to the `plugin_versions` map in the Fabric global configuration block (see [Global configuration]({{< ref "configs.md#global-configuration" >}}) for more details), as shown below:

```hcl
fabric {
plugin_versions = {
"blackstork/crowdstrike" = ">= v0.4.2"
}
}
```

Note the version constraint set for the plugin.

## Configuration

The data source supports the following configuration arguments:

```hcl
config data falcon_detection_details {
# Client ID for accessing CrowdStrike Falcon Platform
#
# Required string.
# Must be non-empty
# For example:
client_id = "some string"
# Client Secret for accessing CrowdStrike Falcon Platform
#
# Required string.
# Must be non-empty
# For example:
client_secret = "some string"
# Member CID for MSSP
#
# Optional string.
# Default value:
member_cid = null
# Falcon cloud abbreviation
#
# Optional string.
# Must be one of: "autodiscover", "us-1", "us-2", "eu-1", "us-gov-1", "gov1"
# For example:
# client_cloud = "us-1"
#
# Default value:
client_cloud = null
}
```

## Usage

The data source supports the following execution arguments:

```hcl
data falcon_detection_details {
# Host search expression using Falcon Query Language (FQL)
#
# Optional string.
# Default value:
filter = null
# limit the number of queried items
#
# Required integer.
# For example:
size = 42
}
```
14 changes: 14 additions & 0 deletions docs/plugins/plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,20 @@
"arguments": [
"size"
]
},
{
"name": "falcon_detection_details",
"type": "data-source",
"config_params": [
"client_cloud",
"client_id",
"client_secret",
"member_cid"
],
"arguments": [
"filter",
"size"
]
}
]
},
Expand Down
120 changes: 120 additions & 0 deletions internal/crowdstrike/data_falcon_detection_details.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package crowdstrike

import (
"context"

"github.com/crowdstrike/gofalcon/falcon"
"github.com/crowdstrike/gofalcon/falcon/client/detects"
"github.com/crowdstrike/gofalcon/falcon/models"
"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"

"github.com/blackstork-io/fabric/pkg/diagnostics"
"github.com/blackstork-io/fabric/plugin"
"github.com/blackstork-io/fabric/plugin/dataspec"
"github.com/blackstork-io/fabric/plugin/dataspec/constraint"
"github.com/blackstork-io/fabric/plugin/plugindata"
)

func makeFalconDetectionDetailsDataSource(loader ClientLoaderFn) *plugin.DataSource {
return &plugin.DataSource{
Doc: "The `falcon_detection_details` data source fetches detection details from Falcon API.",
DataFunc: fetchFalconDetectionDetailsData(loader),
Config: makeDataSourceConfig(),
Args: &dataspec.RootSpec{
Attrs: []*dataspec.AttrSpec{
{
Name: "filter",
Type: cty.String,
Doc: "Host search expression using Falcon Query Language (FQL)",
},
{
Name: "size",
Type: cty.Number,
Constraints: constraint.Integer | constraint.RequiredNonNull,
Doc: "limit the number of queried items",
},
},
},
}
}

func fetchFalconDetectionDetailsData(loader ClientLoaderFn) plugin.RetrieveDataFunc {
return func(ctx context.Context, params *plugin.RetrieveDataParams) (plugindata.Data, diagnostics.Diag) {
cli, err := loader(makeApiConfig(params.Config))
if err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Unable to create falcon client",
Detail: err.Error(),
}}
}

response, err := fetchDetects(ctx, cli.Detects(), params)
if err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to query Falcon detects",
Detail: err.Error(),
}}
}
if err = falcon.AssertNoError(response.GetPayload().Errors); err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to query Falcon detects",
Detail: err.Error(),
}}
}

detectIds := response.GetPayload().Resources
detailResponse, err := fetchDetectsDetails(ctx, cli.Detects(), detectIds)
if err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to fetch Falcon detect details",
Detail: err.Error(),
}}
}
if err = falcon.AssertNoError(response.GetPayload().Errors); err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to fetch Falcon detect details",
Detail: err.Error(),
}}
}

resources := detailResponse.GetPayload().Resources
data, err := encodeResponse(resources)
if err != nil {
return nil, diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to parse response",
Detail: err.Error(),
}}
}
return data, nil
}
}

func fetchDetects(ctx context.Context, cli DetectsClient, params *plugin.RetrieveDataParams) (*detects.QueryDetectsOK, error) {
size, _ := params.Args.GetAttrVal("size").AsBigFloat().Int64()
apiParams := &detects.QueryDetectsParams{}
apiParams.SetLimit(&size)
apiParams.Context = ctx
filter := params.Args.GetAttrVal("filter")
if !filter.IsNull() {
filterStr := filter.AsString()
apiParams.SetFilter(&filterStr)
}
return cli.QueryDetects(apiParams)
}

func fetchDetectsDetails(ctx context.Context, cli DetectsClient, detectIds []string) (*detects.GetDetectSummariesOK, error) {
apiParams := &detects.GetDetectSummariesParams{
Body: &models.MsaIdsRequest{
Ids: detectIds,
},
Context: ctx,
}
return cli.GetDetectSummaries(apiParams)
}
Loading

0 comments on commit 0aedbc0

Please sign in to comment.