From 55d1a32c8c89bb6181226d6e1136ddfcc259ba16 Mon Sep 17 00:00:00 2001 From: Anas Muhammed <102966891+anasmuhmd@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:50:23 +0400 Subject: [PATCH] feat: crowdstrike falcon_cspm_ioms datasource (#245) --- .mockery.yaml | 5 + docs/plugins/crowdstrike/_index.md | 31 ++++ .../data-sources/falcon_cspm_ioms.md | 87 +++++++++ docs/plugins/plugins.json | 20 ++ .../crowdstrike/data_falcon_cspm_ioms.fabric | 38 ++++ go.mod | 20 ++ go.sum | 40 ++++ internal/crowdstrike/cmd/main.go | 14 ++ internal/crowdstrike/data_falcon_cspm_ioms.go | 76 ++++++++ .../crowdstrike/data_falcon_cspm_ioms_test.go | 175 ++++++++++++++++++ internal/crowdstrike/plugin.go | 123 ++++++++++++ internal/crowdstrike/plugin_test.go | 13 ++ mocks/internalpkg/crowdstrike/client.go | 82 ++++++++ .../crowdstrike/cspm_registration_client.go | 108 +++++++++++ tools/docgen/main.go | 2 + 15 files changed, 834 insertions(+) create mode 100644 docs/plugins/crowdstrike/_index.md create mode 100644 docs/plugins/crowdstrike/data-sources/falcon_cspm_ioms.md create mode 100644 examples/templates/crowdstrike/data_falcon_cspm_ioms.fabric create mode 100644 internal/crowdstrike/cmd/main.go create mode 100644 internal/crowdstrike/data_falcon_cspm_ioms.go create mode 100644 internal/crowdstrike/data_falcon_cspm_ioms_test.go create mode 100644 internal/crowdstrike/plugin.go create mode 100644 internal/crowdstrike/plugin_test.go create mode 100644 mocks/internalpkg/crowdstrike/client.go create mode 100644 mocks/internalpkg/crowdstrike/cspm_registration_client.go diff --git a/.mockery.yaml b/.mockery.yaml index 3f8064c1..20f1f7c8 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -52,6 +52,11 @@ packages: interfaces: AzureOpenaiClient: MicrosoftGraphClient: + github.com/blackstork-io/fabric/internal/crowdstrike: + config: + interfaces: + Client: + CspmRegistrationClient: github.com/blackstork-io/fabric/plugin/resolver: config: inpackage: true diff --git a/docs/plugins/crowdstrike/_index.md b/docs/plugins/crowdstrike/_index.md new file mode 100644 index 00000000..cbf578ee --- /dev/null +++ b/docs/plugins/crowdstrike/_index.md @@ -0,0 +1,31 @@ +--- +title: blackstork/crowdstrike +weight: 20 +plugin: + name: blackstork/crowdstrike + description: "" + tags: [] + version: "v0.4.2" + source_github: "https://github.com/blackstork-io/fabric/tree/main/internal/crowdstrike/" +type: docs +hideInMenu: true +--- + +{{< plugin-header "blackstork/crowdstrike" "crowdstrike" "v0.4.2" >}} + +## Installation + +To install the plugin, add it to `plugin_versions` map in the Fabric global configuration block (see [Global configuration]({{< ref "configs.md#global-configuration" >}}) for more details), with a version constraint restricting which available versions of the plugin the codebase is compatible with: + +```hcl +fabric { + plugin_versions = { + "blackstork/crowdstrike" = ">= v0.4.2" + } +} +``` + + +## Data sources + +{{< plugin-resources "crowdstrike" "data-source" >}} diff --git a/docs/plugins/crowdstrike/data-sources/falcon_cspm_ioms.md b/docs/plugins/crowdstrike/data-sources/falcon_cspm_ioms.md new file mode 100644 index 00000000..b66fe9ac --- /dev/null +++ b/docs/plugins/crowdstrike/data-sources/falcon_cspm_ioms.md @@ -0,0 +1,87 @@ +--- +title: "`falcon_cspm_ioms` data source" +plugin: + name: blackstork/crowdstrike + description: "The `falcon_cspm_ioms` data source fetches cloud indicators of misconfigurations (IOMs) from the Falcon security posture management (CSPM) feature" + 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_cspm_ioms" "data source" >}} + +## Description +The `falcon_cspm_ioms` data source fetches cloud indicators of misconfigurations (IOMs) from the Falcon security posture management (CSPM) feature + +## Installation + +To use `falcon_cspm_ioms` 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_cspm_ioms { + # 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_cspm_ioms { + # limit the number of queried items + # + # Required integer. + # For example: + size = 42 +} +``` \ No newline at end of file diff --git a/docs/plugins/plugins.json b/docs/plugins/plugins.json index 66e920f3..a3d534e1 100644 --- a/docs/plugins/plugins.json +++ b/docs/plugins/plugins.json @@ -133,6 +133,26 @@ } ] }, + { + "name": "blackstork/crowdstrike", + "version": "v0.4.2", + "shortname": "crowdstrike", + "resources": [ + { + "name": "falcon_cspm_ioms", + "type": "data-source", + "config_params": [ + "client_cloud", + "client_id", + "client_secret", + "member_cid" + ], + "arguments": [ + "size" + ] + } + ] + }, { "name": "blackstork/elastic", "version": "v0.4.2", diff --git a/examples/templates/crowdstrike/data_falcon_cspm_ioms.fabric b/examples/templates/crowdstrike/data_falcon_cspm_ioms.fabric new file mode 100644 index 00000000..5628a10d --- /dev/null +++ b/examples/templates/crowdstrike/data_falcon_cspm_ioms.fabric @@ -0,0 +1,38 @@ +fabric { + plugin_versions = { + "blackstork/crowdstrike" = ">= 0.4 < 1.0 || 0.4.0-rev0" + } +} + +document "cspm_ioms" { + meta { + name = "example_document" + } + + data falcon_cspm_ioms "cspm" { + config { + client_id = "" + client_secret = "" + client_cloud = "eu-1" + } + size = 100 + } + + title = "List of CSPM IOMS" + + content table { + rows = query_jq(".data.falcon_cspm_ioms.cspm") + columns = [ + { + "header" = "Account Id" + "value" = "{{.row.value.account_id}}" + }, + { + "header" = "Cloud Provider" + "value" = "{{.row.value.cloud_provider}}" + } + ] + } + +} + diff --git a/go.mod b/go.mod index a1540177..b9d9558b 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 github.com/blackstork-io/goldmark-markdown v0.1.3 + github.com/crowdstrike/gofalcon v0.8.0 github.com/elastic/go-elasticsearch/v8 v8.14.0 github.com/evanphx/go-hclog-slog v0.0.0-20240717231540-be48fc4c4df5 github.com/gobwas/glob v0.2.3 @@ -71,6 +72,8 @@ require ( github.com/alecthomas/chroma/v2 v2.10.0 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/containerd v1.7.18 // indirect @@ -89,6 +92,16 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-openapi/analysis v0.22.2 // indirect + github.com/go-openapi/errors v0.22.0 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/loads v0.21.5 // indirect + github.com/go-openapi/runtime v0.27.1 // indirect + github.com/go-openapi/spec v0.20.14 // indirect + github.com/go-openapi/strfmt v0.22.2 // indirect + github.com/go-openapi/swag v0.22.9 // indirect + github.com/go-openapi/validate v0.23.1 // indirect github.com/go-swiss/fonts v0.0.0-20221219152310-0b267088f53d // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect @@ -103,15 +116,18 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/itchyny/timefmt-go v0.1.6 // indirect github.com/jellydator/ttlcache/v3 v3.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/mmcdole/goxpp v1.1.1-0.20240225020742-a0c311522b23 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -123,8 +139,10 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/oklog/run v1.0.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/phpdave11/gofpdf v1.4.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -138,6 +156,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.mongodb.org/mongo-driver v1.14.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect @@ -145,6 +164,7 @@ require ( golang.org/x/crypto v0.24.0 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.16.0 // indirect diff --git a/go.sum b/go.sum index 58f7d77f..9e2fd739 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,10 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/blackstork-io/goldmark-markdown v0.1.3 h1:L8s779mSocytvXAMhypOxqnQFrTUKQlyUjI4ZR+Ni9Q= github.com/blackstork-io/goldmark-markdown v0.1.3/go.mod h1:0r4jctdZOy9oirGo/NikVBdPL4h+3TSs3e2hYRkGEs8= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= @@ -63,6 +67,8 @@ github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/crowdstrike/gofalcon v0.8.0 h1:s2Fa6IDKACjxyaUU8UpLXcCnlsN5I6NQBk/ngjeudg8= +github.com/crowdstrike/gofalcon v0.8.0/go.mod h1:DQ+2zNX9KuuVprwedvsCsPZlnxErohwcQcBxNK+kVJ8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -94,6 +100,26 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= +github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0= +github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8= +github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqvJYto= +github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU= +github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= +github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= +github.com/go-openapi/strfmt v0.22.2 h1:DPYOrm6gexCfZZfXUaXFS4+Jw6HAaIIG0SZ5630f8yw= +github.com/go-openapi/strfmt v0.22.2/go.mod h1:HB/b7TCm91rno75Dembc1dFW/0FPLk5CEXsoF9ReNc4= +github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= +github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= +github.com/go-openapi/validate v0.23.1 h1:3YlF+7NP/pKpaZrSxB88oeVbIuCYlWPGKVMWvPcBMYw= +github.com/go-openapi/validate v0.23.1/go.mod h1:DYvS/pv2Y65SE4hB6Tx+kFC+gS9sPKbqYbY1iwG6z7k= github.com/go-swiss/fonts v0.0.0-20221219152310-0b267088f53d h1:FehRd/9Pu0QpXinklosKByeueVUlR+pZ7iJPMhpanUc= github.com/go-swiss/fonts v0.0.0-20221219152310-0b267088f53d/go.mod h1:kDru5pqfnVEL7+5tYsZOuWRGeWpDJHveRKxRJe5y0hE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= @@ -161,6 +187,8 @@ github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgf github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -182,6 +210,8 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -199,6 +229,8 @@ github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1: github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mmcdole/gofeed v1.3.0 h1:5yn+HeqlcvjMeAI4gu6T+crm7d0anY85+M+v6fIFNG4= @@ -224,10 +256,14 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ= @@ -314,6 +350,8 @@ github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8 github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opentelemetry.io/contrib/bridges/otelslog v0.4.0 h1:i66F95zqmrf3EyN5gu0E2pjTvCRZo/p8XIYidG3vOP8= go.opentelemetry.io/contrib/bridges/otelslog v0.4.0/go.mod h1:JuCiVizZ6ovLZLnYk1nGRUEAnmRJLKGh5v8DmwiKlhY= go.opentelemetry.io/contrib/instrumentation/host v0.51.0 h1:QljwOKW6+mdod9+lK5SzhPzGtB8XQcLNGddK/wYlMI4= @@ -379,6 +417,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/internal/crowdstrike/cmd/main.go b/internal/crowdstrike/cmd/main.go new file mode 100644 index 00000000..4efd1732 --- /dev/null +++ b/internal/crowdstrike/cmd/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/blackstork-io/fabric/internal/crowdstrike" + pluginapiv1 "github.com/blackstork-io/fabric/plugin/pluginapi/v1" +) + +var version string + +func main() { + pluginapiv1.Serve( + crowdstrike.Plugin(version, nil), + ) +} diff --git a/internal/crowdstrike/data_falcon_cspm_ioms.go b/internal/crowdstrike/data_falcon_cspm_ioms.go new file mode 100644 index 00000000..405aecc4 --- /dev/null +++ b/internal/crowdstrike/data_falcon_cspm_ioms.go @@ -0,0 +1,76 @@ +package crowdstrike + +import ( + "context" + + "github.com/crowdstrike/gofalcon/falcon" + "github.com/crowdstrike/gofalcon/falcon/client/cspm_registration" + "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 makeFalconCspmIomsDataSource(loader ClientLoaderFn) *plugin.DataSource { + return &plugin.DataSource{ + Doc: "The `falcon_cspm_ioms` data source fetches cloud indicators of misconfigurations (IOMs) from the Falcon security posture management (CSPM) feature", + DataFunc: fetchFalconCspmIomsData(loader), + Config: makeDataSourceConfig(), + Args: &dataspec.RootSpec{ + Attrs: []*dataspec.AttrSpec{ + { + Name: "size", + Type: cty.Number, + Constraints: constraint.Integer | constraint.RequiredNonNull, + Doc: "limit the number of queried items", + }, + }, + }, + } +} + +func fetchFalconCspmIomsData(loader ClientLoaderFn) plugin.RetrieveDataFunc { + return func(ctx context.Context, params *plugin.RetrieveDataParams) (plugindata.Data, diagnostics.Diag) { + cli, err := loader(makeApiConfig(ctx, params.Config)) + if err != nil { + return nil, diagnostics.Diag{{ + Severity: hcl.DiagError, + Summary: "Unable to create falcon client", + Detail: err.Error(), + }} + } + size, _ := params.Args.GetAttrVal("size").AsBigFloat().Int64() + apiParams := cspm_registration.NewGetConfigurationDetectionsParams().WithDefaults() + apiParams.SetLimit(&size) + apiParams.Context = ctx + response, err := cli.CspmRegistration().GetConfigurationDetections(apiParams) + if err != nil { + return nil, diagnostics.Diag{{ + Severity: hcl.DiagError, + Summary: "Failed to fetch Falcon CSPM IOMs", + Detail: err.Error(), + }} + } + if err = falcon.AssertNoError(response.GetPayload().Errors); err != nil { + return nil, diagnostics.Diag{{ + Severity: hcl.DiagError, + Summary: "Failed to fetch Falcon CSPM IOMs", + Detail: err.Error(), + }} + } + events := response.GetPayload().Resources.Events + data, err := encodeResponse(events) + if err != nil { + return nil, diagnostics.Diag{{ + Severity: hcl.DiagError, + Summary: "Failed to parse response", + Detail: err.Error(), + }} + } + return data, nil + } +} diff --git a/internal/crowdstrike/data_falcon_cspm_ioms_test.go b/internal/crowdstrike/data_falcon_cspm_ioms_test.go new file mode 100644 index 00000000..1dd419c3 --- /dev/null +++ b/internal/crowdstrike/data_falcon_cspm_ioms_test.go @@ -0,0 +1,175 @@ +package crowdstrike_test + +import ( + "context" + "errors" + "testing" + + "github.com/crowdstrike/gofalcon/falcon" + "github.com/crowdstrike/gofalcon/falcon/client/cspm_registration" + "github.com/crowdstrike/gofalcon/falcon/models" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + "github.com/zclconf/go-cty/cty" + + "github.com/blackstork-io/fabric/internal/crowdstrike" + mocks "github.com/blackstork-io/fabric/mocks/internalpkg/crowdstrike" + "github.com/blackstork-io/fabric/pkg/diagnostics/diagtest" + "github.com/blackstork-io/fabric/plugin" + "github.com/blackstork-io/fabric/plugin/plugindata" + "github.com/blackstork-io/fabric/plugin/plugintest" +) + +type CrowdstrikeCspmIomsTestSuite struct { + suite.Suite + plugin *plugin.Schema + cli *mocks.Client + cspmCli *mocks.CspmRegistrationClient +} + +func TestCrowdstrikeCspmIomsSuite(t *testing.T) { + suite.Run(t, &CrowdstrikeCspmIomsTestSuite{}) +} + +func (s *CrowdstrikeCspmIomsTestSuite) SetupSuite() { + s.plugin = crowdstrike.Plugin("1.2.3", func(cfg *falcon.ApiConfig) (client crowdstrike.Client, err error) { + return s.cli, nil + }) +} + +func (s *CrowdstrikeCspmIomsTestSuite) SetupTest() { + s.cli = &mocks.Client{} + s.cspmCli = &mocks.CspmRegistrationClient{} +} + +func (s *CrowdstrikeCspmIomsTestSuite) TearDownTest() { + s.cli.AssertExpectations(s.T()) +} + +func (s *CrowdstrikeCspmIomsTestSuite) TestSchema() { + schema := s.plugin.DataSources["falcon_cspm_ioms"] + s.Require().NotNil(schema) + s.NotNil(schema.Config) + s.NotNil(schema.Args) + s.NotNil(schema.DataFunc) +} + +func (s *CrowdstrikeCspmIomsTestSuite) String(val string) *string { + return &val +} + +func (s *CrowdstrikeCspmIomsTestSuite) TestBasic() { + s.cli.On("CspmRegistration").Return(s.cspmCli) + s.cspmCli.On("GetConfigurationDetections", mock.MatchedBy(func(params *cspm_registration.GetConfigurationDetectionsParams) bool { + return params.Limit != nil && *params.Limit == 10 + })).Return(&cspm_registration.GetConfigurationDetectionsOK{ + Payload: &models.RegistrationExternalIOMEventResponse{ + Resources: &models.RegistrationIOMResources{ + Events: []*models.RegistrationIOMEvent{ + { + AccountID: s.String("test_account_id_1"), + AccountName: s.String("test_account_name_1"), + AzureTenantID: s.String("test_azure_tenant_id_1"), + Cid: s.String("test_cid_1"), + CloudProvider: s.String("test_cloud_provider_1"), + }, + { + AccountID: s.String("test_account_id_2"), + AccountName: s.String("test_account_name_2"), + AzureTenantID: s.String("test_azure_tenant_id_2"), + Cid: s.String("test_cid_2"), + CloudProvider: s.String("test_cloud_provider_2"), + }, + }, + }, + }, + }, nil) + ctx := context.Background() + data, diags := s.plugin.RetrieveData(ctx, "falcon_cspm_ioms", &plugin.RetrieveDataParams{ + Config: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Config). + SetAttr("client_id", cty.StringVal("test")). + SetAttr("client_secret", cty.StringVal("test")). + Decode(), + Args: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Args). + SetAttr("size", cty.NumberIntVal(10)). + Decode(), + }) + s.Require().Nil(diags) + list := data.AsPluginData().(plugindata.List) + s.Len(list, 2) + s.Subset(list[0], plugindata.Map{ + "account_id": plugindata.String("test_account_id_1"), + "account_name": plugindata.String("test_account_name_1"), + "azure_tenant_id": plugindata.String("test_azure_tenant_id_1"), + "cid": plugindata.String("test_cid_1"), + "cloud_provider": plugindata.String("test_cloud_provider_1"), + }) + s.Subset(list[1], plugindata.Map{ + "account_id": plugindata.String("test_account_id_2"), + "account_name": plugindata.String("test_account_name_2"), + "azure_tenant_id": plugindata.String("test_azure_tenant_id_2"), + "cid": plugindata.String("test_cid_2"), + "cloud_provider": plugindata.String("test_cloud_provider_2"), + }) +} + +func (s *CrowdstrikeCspmIomsTestSuite) TestPayloadErrors() { + s.cli.On("CspmRegistration").Return(s.cspmCli) + s.cspmCli.On("GetConfigurationDetections", mock.MatchedBy(func(params *cspm_registration.GetConfigurationDetectionsParams) bool { + return params.Limit != nil && *params.Limit == 10 + })).Return(&cspm_registration.GetConfigurationDetectionsOK{ + Payload: &models.RegistrationExternalIOMEventResponse{ + Errors: []*models.MsaAPIError{{ + Message: s.String("something went wrong"), + }}, + }, + }, nil) + ctx := context.Background() + _, diags := s.plugin.RetrieveData(ctx, "falcon_cspm_ioms", &plugin.RetrieveDataParams{ + Config: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Config). + SetAttr("client_id", cty.StringVal("test")). + SetAttr("client_secret", cty.StringVal("test")). + Decode(), + Args: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Args). + SetAttr("size", cty.NumberIntVal(10)). + Decode(), + }) + diagtest.Asserts{{ + diagtest.IsError, + diagtest.SummaryContains("Failed to fetch Falcon CSPM IOMs"), + diagtest.DetailContains("something went wrong"), + }}.AssertMatch(s.T(), diags, nil) +} + +func (s *CrowdstrikeCspmIomsTestSuite) TestError() { + s.cli.On("CspmRegistration").Return(s.cspmCli) + s.cspmCli.On("GetConfigurationDetections", mock.MatchedBy(func(params *cspm_registration.GetConfigurationDetectionsParams) bool { + return params.Limit != nil && *params.Limit == 10 + })).Return(nil, errors.New("something went wrong")) + ctx := context.Background() + _, diags := s.plugin.RetrieveData(ctx, "falcon_cspm_ioms", &plugin.RetrieveDataParams{ + Config: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Config). + SetAttr("client_id", cty.StringVal("test")). + SetAttr("client_secret", cty.StringVal("test")). + Decode(), + Args: plugintest.NewTestDecoder(s.T(), s.plugin.DataSources["falcon_cspm_ioms"].Args). + SetAttr("size", cty.NumberIntVal(10)). + Decode(), + }) + diagtest.Asserts{{ + diagtest.IsError, + diagtest.SummaryContains("Failed to fetch Falcon CSPM IOMs"), + diagtest.DetailContains("something went wrong"), + }}.AssertMatch(s.T(), diags, nil) +} + +func (s *CrowdstrikeCspmIomsTestSuite) TestMissingArgs() { + plugintest.NewTestDecoder( + s.T(), + s.plugin.DataSources["falcon_cspm_ioms"].Args, + ).Decode([]diagtest.Assert{ + diagtest.IsError, + diagtest.SummaryEquals("Missing required attribute"), + diagtest.DetailContains("size"), + }) +} diff --git a/internal/crowdstrike/plugin.go b/internal/crowdstrike/plugin.go new file mode 100644 index 00000000..3bd30a4e --- /dev/null +++ b/internal/crowdstrike/plugin.go @@ -0,0 +1,123 @@ +package crowdstrike + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/crowdstrike/gofalcon/falcon" + "github.com/crowdstrike/gofalcon/falcon/client" + "github.com/crowdstrike/gofalcon/falcon/client/cspm_registration" + "github.com/zclconf/go-cty/cty" + + "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" +) + +type CspmRegistrationClient interface { + GetConfigurationDetections(params *cspm_registration.GetConfigurationDetectionsParams, opts ...cspm_registration.ClientOption) (*cspm_registration.GetConfigurationDetectionsOK, error) +} + +type Client interface { + CspmRegistration() CspmRegistrationClient +} + +type ClientAdapter struct { + client *client.CrowdStrikeAPISpecification +} + +func (c *ClientAdapter) CspmRegistration() CspmRegistrationClient { + return c.client.CspmRegistration +} + +type ClientLoaderFn func(cfg *falcon.ApiConfig) (client Client, err error) + +var DefaultClientLoader = func(cfg *falcon.ApiConfig) (Client, error) { + client, err := falcon.NewClient(cfg) + if err != nil { + return nil, err + } + return &ClientAdapter{client}, nil +} + +func Plugin(version string, loader ClientLoaderFn) *plugin.Schema { + if loader == nil { + loader = DefaultClientLoader + } + return &plugin.Schema{ + Name: "blackstork/crowdstrike", + Version: version, + DataSources: plugin.DataSources{ + "falcon_cspm_ioms": makeFalconCspmIomsDataSource(loader), + }, + } +} + +// shared config for all data sources +func makeDataSourceConfig() *dataspec.RootSpec { + return &dataspec.RootSpec{ + Attrs: []*dataspec.AttrSpec{ + { + Name: "client_id", + Type: cty.String, + Constraints: constraint.RequiredMeaningful, + Doc: "Client ID for accessing CrowdStrike Falcon Platform", + }, + { + Name: "client_secret", + Type: cty.String, + Constraints: constraint.RequiredMeaningful, + Secret: true, + Doc: "Client Secret for accessing CrowdStrike Falcon Platform", + }, + { + Name: "member_cid", + Type: cty.String, + Doc: "Member CID for MSSP", + }, + { + Name: "client_cloud", + Type: cty.String, + OneOf: []cty.Value{ + cty.StringVal("autodiscover"), + cty.StringVal("us-1"), + cty.StringVal("us-2"), + cty.StringVal("eu-1"), + cty.StringVal("us-gov-1"), + cty.StringVal("gov1"), + }, + Doc: "Falcon cloud abbreviation", + ExampleVal: cty.StringVal("us-1"), + }, + }, + } +} + +func makeApiConfig(ctx context.Context, cfg *dataspec.Block) *falcon.ApiConfig { + clientId := cfg.GetAttrVal("client_id").AsString() + clientSecret := cfg.GetAttrVal("client_secret").AsString() + apiCfg := &falcon.ApiConfig{ + ClientId: clientId, + ClientSecret: clientSecret, + } + memberCID := cfg.GetAttrVal("member_cid") + if !memberCID.IsNull() { + apiCfg.MemberCID = memberCID.AsString() + } + clientCloud := cfg.GetAttrVal("client_cloud") + if !clientCloud.IsNull() { + apiCfg.Cloud = falcon.Cloud(clientCloud.AsString()) + } + apiCfg.Context = ctx + return apiCfg +} + +func encodeResponse(data any) (plugindata.Data, error) { + raw, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("failed to encode issue: %w", err) + } + return plugindata.UnmarshalJSON(raw) +} diff --git a/internal/crowdstrike/plugin_test.go b/internal/crowdstrike/plugin_test.go new file mode 100644 index 00000000..9fc6eeed --- /dev/null +++ b/internal/crowdstrike/plugin_test.go @@ -0,0 +1,13 @@ +package crowdstrike + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPlugin_Schema(t *testing.T) { + schema := Plugin("1.2.3", nil) + assert.Equal(t, "blackstork/crowdstrike", schema.Name) + assert.Equal(t, "1.2.3", schema.Version) +} diff --git a/mocks/internalpkg/crowdstrike/client.go b/mocks/internalpkg/crowdstrike/client.go new file mode 100644 index 00000000..b166884c --- /dev/null +++ b/mocks/internalpkg/crowdstrike/client.go @@ -0,0 +1,82 @@ +// Code generated by mockery v2.42.1. DO NOT EDIT. + +package crowdstrike_mocks + +import ( + crowdstrike "github.com/blackstork-io/fabric/internal/crowdstrike" + mock "github.com/stretchr/testify/mock" +) + +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +type Client_Expecter struct { + mock *mock.Mock +} + +func (_m *Client) EXPECT() *Client_Expecter { + return &Client_Expecter{mock: &_m.Mock} +} + +// CspmRegistration provides a mock function with given fields: +func (_m *Client) CspmRegistration() crowdstrike.CspmRegistrationClient { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CspmRegistration") + } + + var r0 crowdstrike.CspmRegistrationClient + if rf, ok := ret.Get(0).(func() crowdstrike.CspmRegistrationClient); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(crowdstrike.CspmRegistrationClient) + } + } + + return r0 +} + +// Client_CspmRegistration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CspmRegistration' +type Client_CspmRegistration_Call struct { + *mock.Call +} + +// CspmRegistration is a helper method to define mock.On call +func (_e *Client_Expecter) CspmRegistration() *Client_CspmRegistration_Call { + return &Client_CspmRegistration_Call{Call: _e.mock.On("CspmRegistration")} +} + +func (_c *Client_CspmRegistration_Call) Run(run func()) *Client_CspmRegistration_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Client_CspmRegistration_Call) Return(_a0 crowdstrike.CspmRegistrationClient) *Client_CspmRegistration_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Client_CspmRegistration_Call) RunAndReturn(run func() crowdstrike.CspmRegistrationClient) *Client_CspmRegistration_Call { + _c.Call.Return(run) + return _c +} + +// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClient(t interface { + mock.TestingT + Cleanup(func()) +}) *Client { + mock := &Client{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/internalpkg/crowdstrike/cspm_registration_client.go b/mocks/internalpkg/crowdstrike/cspm_registration_client.go new file mode 100644 index 00000000..95cd6008 --- /dev/null +++ b/mocks/internalpkg/crowdstrike/cspm_registration_client.go @@ -0,0 +1,108 @@ +// Code generated by mockery v2.42.1. DO NOT EDIT. + +package crowdstrike_mocks + +import ( + cspm_registration "github.com/crowdstrike/gofalcon/falcon/client/cspm_registration" + mock "github.com/stretchr/testify/mock" +) + +// CspmRegistrationClient is an autogenerated mock type for the CspmRegistrationClient type +type CspmRegistrationClient struct { + mock.Mock +} + +type CspmRegistrationClient_Expecter struct { + mock *mock.Mock +} + +func (_m *CspmRegistrationClient) EXPECT() *CspmRegistrationClient_Expecter { + return &CspmRegistrationClient_Expecter{mock: &_m.Mock} +} + +// GetConfigurationDetections provides a mock function with given fields: params, opts +func (_m *CspmRegistrationClient) GetConfigurationDetections(params *cspm_registration.GetConfigurationDetectionsParams, opts ...cspm_registration.ClientOption) (*cspm_registration.GetConfigurationDetectionsOK, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, params) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetConfigurationDetections") + } + + var r0 *cspm_registration.GetConfigurationDetectionsOK + var r1 error + if rf, ok := ret.Get(0).(func(*cspm_registration.GetConfigurationDetectionsParams, ...cspm_registration.ClientOption) (*cspm_registration.GetConfigurationDetectionsOK, error)); ok { + return rf(params, opts...) + } + if rf, ok := ret.Get(0).(func(*cspm_registration.GetConfigurationDetectionsParams, ...cspm_registration.ClientOption) *cspm_registration.GetConfigurationDetectionsOK); ok { + r0 = rf(params, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*cspm_registration.GetConfigurationDetectionsOK) + } + } + + if rf, ok := ret.Get(1).(func(*cspm_registration.GetConfigurationDetectionsParams, ...cspm_registration.ClientOption) error); ok { + r1 = rf(params, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CspmRegistrationClient_GetConfigurationDetections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetConfigurationDetections' +type CspmRegistrationClient_GetConfigurationDetections_Call struct { + *mock.Call +} + +// GetConfigurationDetections is a helper method to define mock.On call +// - params *cspm_registration.GetConfigurationDetectionsParams +// - opts ...cspm_registration.ClientOption +func (_e *CspmRegistrationClient_Expecter) GetConfigurationDetections(params interface{}, opts ...interface{}) *CspmRegistrationClient_GetConfigurationDetections_Call { + return &CspmRegistrationClient_GetConfigurationDetections_Call{Call: _e.mock.On("GetConfigurationDetections", + append([]interface{}{params}, opts...)...)} +} + +func (_c *CspmRegistrationClient_GetConfigurationDetections_Call) Run(run func(params *cspm_registration.GetConfigurationDetectionsParams, opts ...cspm_registration.ClientOption)) *CspmRegistrationClient_GetConfigurationDetections_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]cspm_registration.ClientOption, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(cspm_registration.ClientOption) + } + } + run(args[0].(*cspm_registration.GetConfigurationDetectionsParams), variadicArgs...) + }) + return _c +} + +func (_c *CspmRegistrationClient_GetConfigurationDetections_Call) Return(_a0 *cspm_registration.GetConfigurationDetectionsOK, _a1 error) *CspmRegistrationClient_GetConfigurationDetections_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *CspmRegistrationClient_GetConfigurationDetections_Call) RunAndReturn(run func(*cspm_registration.GetConfigurationDetectionsParams, ...cspm_registration.ClientOption) (*cspm_registration.GetConfigurationDetectionsOK, error)) *CspmRegistrationClient_GetConfigurationDetections_Call { + _c.Call.Return(run) + return _c +} + +// NewCspmRegistrationClient creates a new instance of CspmRegistrationClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCspmRegistrationClient(t interface { + mock.TestingT + Cleanup(func()) +}) *CspmRegistrationClient { + mock := &CspmRegistrationClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/tools/docgen/main.go b/tools/docgen/main.go index c99b5b2e..9538df2b 100644 --- a/tools/docgen/main.go +++ b/tools/docgen/main.go @@ -16,6 +16,7 @@ import ( "github.com/spf13/pflag" "github.com/blackstork-io/fabric/internal/builtin" + "github.com/blackstork-io/fabric/internal/crowdstrike" "github.com/blackstork-io/fabric/internal/elastic" "github.com/blackstork-io/fabric/internal/github" "github.com/blackstork-io/fabric/internal/graphql" @@ -278,6 +279,7 @@ func main() { nistnvd.Plugin(version, nil), snyk.Plugin(version, nil), microsoft.Plugin(version, nil, nil, nil), + crowdstrike.Plugin(version, nil), } // generate markdown for each plugin for _, p := range plugins {