Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (10.3%) to scientific vocabulary
Last synced: 6 months ago · JSON representation ·

Repository

Basic Info
  • Host: GitHub
  • Owner: CrowdStrike
  • License: mit
  • Language: Go
  • Default Branch: main
  • Homepage:
  • Size: 201 KB
Statistics
  • Stars: 5
  • Watchers: 5
  • Forks: 2
  • Open Issues: 1
  • Releases: 44
Created over 2 years ago · Last pushed 10 months ago
Metadata Files
Readme License Code of conduct Citation Security Support

README.md

CrowdStrike Falcon

Foundry Function as a Service Go SDK

foundry-fn-go is a community-driven, open source project designed to enable the authoring of functions. While not a formal CrowdStrike product, foundry-fn-go is maintained by CrowdStrike and supported in partnership with the open source developer community.

Installation ⚙️

Via go get

The SDK can be installed or updated via go get:

shell go get github.com/CrowdStrike/foundry-fn-go

From source

The SDK can be built from source via standard build:

shell go mod tidy go build .

Quickstart 💫

Code

Add the SDK to your project by following the installation instructions above, then create your main.go:

```go package main

import ( "context" "errors" "log/slog" "net/http"

fdk "github.com/CrowdStrike/foundry-fn-go"

)

func main() { fdk.Run(context.Background(), newHandler) }

type request struct { Name string json:"name" Val string json:"val" }

// newHandler here is showing how a config is integrated. It is using generics, // so we can unmarshal the config into a concrete type and then validate it. The // OK method is run to validate the contents of the config. func newHandler(_ context.Context, logger *slog.Logger, cfg config) fdk.Handler { mux := fdk.NewMux() mux.Get("/name", fdk.HandlerFn(func(_ context.Context, r fdk.Request) fdk.Response { return fdk.Response{ Body: fdk.JSON(map[string]string{"name": r.Params.Query.Get("name")}), Code: 200, } })) mux.Post("/echo", fdk.HandlerFnOfOK(func(_ context.Context, r fdk.RequestOf[request]) fdk.Response { if r.Body.Name == "kaboom" { logger.Error("encountered the kaboom") } return fdk.Response{ Body: fdk.JSON(r.Body), Code: 201, Header: http.Header{"X-Cs-Method": []string{r.Method}}, } })) return mux }

type config struct { Int int json:"integer" Str string json:"string" }

func (c config) OK() error { var errs []error if c.Int < 1 { errs = append(errs, errors.New("integer must be greater than 0")) } if c.Str == "" { errs = append(errs, errors.New("non empty string must be provided")) } return errors.Join(errs...) }

```

  1. config: A type the raw json config is unmarshalled into.
  2. logger: A dedicated logger is provided to capture function logs in all environments (both locally and distributed).
    1. Using a different logger may produce logs in the runtime but won't make it into the logscale infrastructure.
  3. Request: Request payload and metadata. At the time of this writing, the Request struct consists of:
    1. Body: The input io.Reader for the payload as given in the Function Gateway body payload field or streamed in.
    2. Params: Contains request headers and query parameters.
    3. URL: The request path relative to the function as a string.
    4. Method: The request HTTP method or verb.
    5. Context: Caller-supplied raw context.
    6. AccessToken: Caller-supplied access token.
  4. RequestOf: The same as Request only that the Body field is json unmarshalled into the generic type (i.e. request type above)
  5. Response
    1. The Response contains fields Body (the payload of the response), Code (an HTTP status code), Errors (a slice of APIErrors), and Headers (a map of any special HTTP headers which should be present on the response).
  6. main(): Initialization and bootstrap logic all contained with fdk.Run and handler constructor.

more examples can be found at:

Testing locally

The SDK provides an out-of-the-box runtime for executing the function. A basic HTTP server will be listening on port 8081.

```shell

build the project which uses the sdk

cd my-project && go mod tidy && go build -o run_me .

run the executable. config should be in json format here.

CSFNCONFIGPATH=$PATHTOCONFIGJSON ./run_me ```

Requests can now be made against the executable.

shell curl -X POST http://localhost:8081/ \ -H "Content-Type: application/json" \ --data '{ "body": { "foo": "bar" }, "method": "POST", "url": "/greetings" }'

Convenience Functionality 🧰

gofalcon

Foundry Function integrates with gofalcon in a few simple lines.

```go package main

import ( "context" "log/slog"

fdk "github.com/CrowdStrike/foundry-fn-go"
"github.com/crowdstrike/gofalcon/falcon"
"github.com/crowdstrike/gofalcon/falcon/client"

)

func newHandler(_ context.Context, _ *slog.Logger, cfg config) fdk.Handler { mux := fdk.NewMux() mux.Post("/echo", fdk.HandlerFn(func(ctx context.Context, r fdk.Request) fdk.Response { client, err := newFalconClient(ctx, r.AccessToken) if err != nil { return fdk.ErrResp(fdk.APIError{Code: 500, Message: err.Error()}) }

    // we have a valid gofalcon client
}))
return mux

}

func newFalconClient(ctx context.Context, token string) (*client.CrowdStrikeAPISpecification, error) { opts := fdk.FalconClientOpts() return falcon.NewClient(&falcon.ApiConfig{ AccessToken: token, Cloud: falcon.Cloud(opts.Cloud), Context: ctx, UserAgentOverride: opts.UserAgent, }) }

// omitting rest of implementation

```

Integration with Falcon Fusion workflows

When integrating with a Falcon Fusion workflow, the Request.Context can be decoded into WorkflowCtx type. You may json unmarshal into that type. The type provides some additional context from the workflow. This context is from the execution of the workflow, and may be dynamic in some usecases. To simplify things further for authors, we have introduced two handler functions to remove the boilerplate of dealing with a workflow.

```go package somefn

import ( "context" "log/slog"

fdk "github.com/CrowdStrike/foundry-fn-go"

)

type reqBody struct { Foo string json:"foo" }

func New(ctx context.Context, _ *slog.Logger, _ fdk.SkipCfg) fdk.Handler { m := fdk.NewMux()

// for get/delete reqs use HandleWorkflow. The path is just an examples, any payh can be used.
m.Get("/workflow", fdk.HandleWorkflow(func(ctx context.Context, r fdk.Request, workflowCtx fdk.WorkflowCtx) fdk.Response {
    // ... trim impl
}))

// for handlers that expect a request body (i.e. PATCH/POST/PUT)
m.Post("/workflow", fdk.HandleWorkflowOf(func(ctx context.Context, r fdk.RequestOf[reqBody], workflowCtx fdk.WorkflowCtx) fdk.Response {
    // .. trim imple
}))

return m

}

```

Working with Request and Response Schemas

Within the fdktest pkg, we maintain test funcs for validating a schema and its integration with a handler. Example:

```go package somefn_test

import ( "context" "net/http" "testing"

fdk "github.com/CrowdStrike/foundry-fn-go"
"github.com/CrowdStrike/foundry-fn-go/fdktest"

)

func TestHandlerIntegration(t *testing.T) { reqSchema := { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "postalCode": { "type": "string", "description": "The person's first name.", "pattern": "\\d{5}" }, "optional": { "type": "string", "description": "The person's last name." } }, "required": [ "postalCode" ] }

respSchema := `{

"$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string", "description": "The person's first name.", "enum": ["bar"] } }, "required": [ "foo" ] }` handler := fdk.HandlerFn(func(ctx context.Context, r fdk.Request) fdk.Response { return fdk.Response{Body: fdk.JSON(map[string]string{"foo": "bar"})} })

req := fdk.Request{
    URL:    "/",
    Method: http.MethodPost,
    Body:   json.RawMessage(`{"postalCode": "55755"}`),
}

err := fdktest.HandlerSchemaOK(handler, req, reqSchema, respSchema)
if err != nil {
    t.Fatal("unexpected err: ", err)
}

}

```

A note on os.Exit

Please refrain from using os.Exit. When an error is encountered, we want to return a message to the caller. Otherwise, it'll os.Exit and all stakeholders will have no idea what to make of it. Instead, use something like the following in fdk.Run:

```go package main

import ( "context" "log/slog" "net/http"

fdk "github.com/CrowdStrike/foundry-fn-go"

)

func newHandler(_ context.Context, logger *slog.Logger, _ fdk.SkipCfg) fdk.Handler { foo, err := newFoo() if err != nil { // leave yourself/author the nitty-gritty details and return to the end user/caller // a valid error that doesn't expose all the implementation details logger.Error("failed to create foo", "err", err.Error()) return fdk.ErrHandler(fdk.APIError{Code: http.StatusInternalServerError, Message: "unexpected error starting function"}) }

mux := fdk.NewMux()
// ...trim rest of setup

return mux

}

```



WE STOP BREACHES

Owner

  • Name: CrowdStrike
  • Login: CrowdStrike
  • Kind: organization
  • Email: github@crowdstrike.com
  • Location: United States of America

Citation (CITATION.cff)

cff-version: 1.2.0
title: 'CrowdStrike Foundry Function as a Service for Go'
message: >-
  If you use this software, and wish to cite the origins, 
  please use metadata from this file.
type: software
authors:
  - given-names: 
    family-names: CrowdStrike
    email: foundry-fn-go@crowdstrike.com
  - given-names: John
    family-names: Stone
    affiliation: CrowdStrike
  - given-names: Chris
    family-names: Cannon
    affiliation: CrowdStrike
  - given-names: Johnny
    family-names: Steenbergen
    affiliation: CrowdStrike
repository-code: 'https://github.com/CrowdStrike/foundry-fn-go'
url: 'https://www.crowdstrike.com'
repository-artifact: 'https://pkg.go.dev/github.com/crowdstrike/foundry-fn-go'
abstract: >-
  The CrowdStrike Foundry Function as a Service SDK
  is a community-driven, open source project designed
  to enable the authoring of functions.
keywords:
  - crowdstrike
  - oauth2
  - crowdstrike-api
  - crowdstrike-falcon-api
  - crowdstrike-foundry
  - go
  - windows
  - linux
  - mac
license: MIT

GitHub Events

Total
  • Release event: 6
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 1
  • Push event: 14
  • Pull request review event: 17
  • Pull request review comment event: 13
  • Pull request event: 11
  • Fork event: 1
  • Create event: 12
Last Year
  • Release event: 6
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 1
  • Push event: 14
  • Pull request review event: 17
  • Pull request review comment event: 13
  • Pull request event: 11
  • Fork event: 1
  • Create event: 12

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 56
  • Total Committers: 4
  • Avg Commits per committer: 14.0
  • Development Distribution Score (DDS): 0.161
Past Year
  • Commits: 24
  • Committers: 3
  • Avg Commits per committer: 8.0
  • Development Distribution Score (DDS): 0.167
Top Committers
Name Email Commits
Johnny Steenbergen j****n@c****m 47
Chris Cannon c****n@c****m 4
johns31459 1****9 3
Evan Stoner e****r@c****m 2
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 3
  • Total pull requests: 39
  • Average time to close issues: 3 months
  • Average time to close pull requests: 7 days
  • Total issue authors: 1
  • Total pull request authors: 5
  • Average comments per issue: 0.0
  • Average comments per pull request: 0.28
  • Merged pull requests: 34
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 11
  • Average time to close issues: N/A
  • Average time to close pull requests: 17 days
  • Issue authors: 0
  • Pull request authors: 3
  • Average comments per issue: 0
  • Average comments per pull request: 0.09
  • Merged pull requests: 9
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • jsteenb2 (4)
Pull Request Authors
  • jsteenb2 (48)
  • johns31459 (4)
  • evanstoner (2)
  • PaulRosset (1)
  • ffalor (1)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 4
  • Total downloads: unknown
  • Total dependent packages: 0
    (may contain duplicates)
  • Total dependent repositories: 0
    (may contain duplicates)
  • Total versions: 248
proxy.golang.org: github.com/CrowdSTrike/foundry-fn-go
  • Versions: 62
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 8.4%
Dependent repos count: 10.6%
Average: 11.7%
Forks count: 13.3%
Stargazers count: 14.6%
Last synced: 6 months ago
proxy.golang.org: github.com/Crowdstrike/foundry-fn-go
  • Versions: 62
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 8.5%
Dependent repos count: 10.4%
Average: 12.2%
Forks count: 13.4%
Stargazers count: 16.4%
Last synced: 7 months ago
proxy.golang.org: github.com/crowdstrike/foundry-fn-go
  • Versions: 62
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 8.9%
Dependent repos count: 10.6%
Average: 12.4%
Forks count: 13.6%
Stargazers count: 16.6%
Last synced: 6 months ago
proxy.golang.org: github.com/CrowdStrike/foundry-fn-go
  • Versions: 62
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 8.9%
Dependent repos count: 10.6%
Average: 12.4%
Forks count: 13.6%
Stargazers count: 16.6%
Last synced: 7 months ago

Dependencies

.github/workflows/go.yml actions
  • actions/checkout v3 composite
  • actions/setup-go v4 composite
go.mod go
  • github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
  • github.com/blang/semver/v4 v4.0.0
  • github.com/crowdstrike/gofalcon v0.3.1
  • github.com/davecgh/go-spew v1.1.1
  • github.com/go-logr/logr v1.2.3
  • github.com/go-logr/stdr v1.2.2
  • github.com/go-openapi/analysis v0.21.4
  • github.com/go-openapi/errors v0.20.4
  • github.com/go-openapi/jsonpointer v0.19.5
  • github.com/go-openapi/jsonreference v0.20.0
  • github.com/go-openapi/loads v0.21.2
  • github.com/go-openapi/runtime v0.26.0
  • github.com/go-openapi/spec v0.20.8
  • github.com/go-openapi/strfmt v0.21.7
  • github.com/go-openapi/swag v0.22.4
  • github.com/go-openapi/validate v0.22.1
  • github.com/golang/protobuf v1.5.2
  • github.com/josharian/intern v1.0.0
  • github.com/mailru/easyjson v0.7.7
  • github.com/mitchellh/mapstructure v1.5.0
  • github.com/oklog/ulid v1.3.1
  • github.com/opentracing/opentracing-go v1.2.0
  • github.com/pmezard/go-difflib v1.0.0
  • github.com/sirupsen/logrus v1.9.3
  • github.com/stretchr/testify v1.8.2
  • go.mongodb.org/mongo-driver v1.11.3
  • go.opentelemetry.io/otel v1.14.0
  • go.opentelemetry.io/otel/trace v1.14.0
  • golang.org/x/net v0.11.0
  • golang.org/x/oauth2 v0.9.0
  • golang.org/x/sys v0.9.0
  • google.golang.org/appengine v1.6.7
  • google.golang.org/protobuf v1.28.0
  • gopkg.in/yaml.v2 v2.4.0
  • gopkg.in/yaml.v3 v3.0.1
go.sum go
  • 195 dependencies