fdk

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2023 License: MIT Imports: 20 Imported by: 3

README

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:

go get github.com/CrowdStrike/foundry-fn-go
From source

The SDK can be built from source via standard build:

go mod tidy
go build .

Quickstart 💫

Code

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

package main

import (
    /* omitting other imports */
    fdk "github.com/CrowdStrike/foundry-fn-go"
)

var (
    cfg *fdk.Config /*** (1) ***/
)

/*** (2) ***/
func RunHandler(_ context.Context, request fdk.Request /*** (3) ***/) (fdk.Response, error) {
    b := bytes.NewBuffer(nil)
    err := json.NewEncoder(b).Encode(request)
    return fdk.Response{Body: b.Bytes(), Code: 200}, err /*** (4) ***/
}

func main() { /*** (5) ***/
    cfg = &fdk.Config{}
    err := fdk.LoadConfig(cfg) /*** (6) ***/
    if err != nil && err != fdk.ErrNoConfig {
        os.Exit(1)
    }
    fdk.Start(RunHandler) /*** (7) ***/
}
  1. cfg: A global variable which holds any loaded configuration. Should be initialized exactly once within main().
  2. RunHandler(): Called once on each inbound request. This is where the business logic of the function should exist.
  3. request: Request payload and metadata. At the time of this writing, the Request struct consists of:
    1. Body: The raw request payload as given in the Function Gateway body payload field.
    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. Return from RunHandler(): Returns two values - a Response and an error.
    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).
    2. The error is an indication that there was a transient error on the request. In production, returning a non-nil error will result in a retry of the request. There is a limited number of reties before the request will be dead-lettered. Do not return an error unless you actually want the request to be retried.
  5. main(): Initialization and bootstrap logic. Called exactly once at the startup of the runtime. Any initialization logic should exist prior to calling fdk.Start().
  6. LoadConfig(cfg): Loads any configuration deployed along with function into the *fdk.Config. Will return an ErrNoConfig if no configuration was available to be loaded. Will return another error if there was some other error loading the configuration.
  7. fdk.Start(RunHandler): Binds the handler function to the runtime and starts listening to inbound requests.
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.

# build the project which uses the sdk
cd my-project && go mod tidy && go build -o run_me .

# run the executable
./run_me

Requests can now be made against the executable.

curl -X POST http://localhost:8081/echo \
  -H "Content-Type: application/json" \
  --data '{"foo": "bar"}'

Convenience Functionality 🧰

gofalcon

Foundry Function Go ships with gofalcon pre-integrated and a convenience constructor. While it is not strictly necessary to use convenience function, it is recommended.

Important: Create a new instance of the gofalcon client on each request.

import (
    /* omitting other imports */
    fdk "github.com/crowdstrike/foundry-fn-go"
)

func RunHandler(ctx context.Context, request fdk.Request) (fdk.Response, error) {
    /* ... omitting other code ... */
    
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // !!! create a new client instance on each request !!!
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    client, err := fdk.FalconClient(ctx, request)
    if err != nil {
        if err == fdk.ErrFalconNoToken {
            // not a processable request
            return fdk.Response{ /* snip */ }, nil
        }
        // some other error - see gofalcon documentation
    }
    
    /* ... omitting other code ... */
}


WE STOP BREACHES

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// ErrConfigPointer is returned when attempting to load config into a non-pointer interface{}
	ErrConfigPointer = errors.New("config must be loaded into a pointer type")

	// ErrNoConfig indicates that no config env variable was provided.
	ErrNoConfig = fmt.Errorf("no value provided for %s", envFnConfigPath)

	// ErrFalconNoToken indicates that no access token was on the request handed to the FalconClient convenience function.
	ErrFalconNoToken = errors.New("falcon client requires an access token")
)

Functions

func FalconClient

FalconClient returns a new instance of the GoFalcon client. If the client cannot be created or if there is no access token in the request, an error is returned.

func LoadConfig

func LoadConfig(config interface{}) error

LoadConfig loads the configuration contents into the passed in interface type

func Start

func Start(f Handler)

Start is called with a handler of various function handler signatures It will start a local http server serving your function

Types

type APIError

type APIError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

APIError is a baic api error

type BaseResponseV1

type BaseResponseV1 struct {
	Errors []APIError `json:"errors,omitempty"`
}

BaseResponseV1 is a basic response

type Config

type Config map[string]interface{}

Config is a simple config map

type ExecuteCommandRequestV1

type ExecuteCommandRequestV1 struct {
	Resources []ExecuteFunctionV1 `json:"resources" description:"List of functions to execute"`
}

ExecuteCommandRequestV1 stores information for execute command requests

type ExecuteFunctionResultV1

type ExecuteFunctionResultV1 struct {
	ID           string              `json:"id" description:"ID of the function that was executed in the format 'function_id:version.operation_id'."`
	StatusCode   int                 `json:"status_code" description:"The response status code from the partner service."`
	Headers      map[string][]string `json:"headers,omitempty" description:"The response headers from the partner service"`
	ResponseBody json.RawMessage     `json:"response_body,omitempty" description:"The response body from the partner service"`
}

ExecuteFunctionResultV1 is the response body for executing a function

type ExecuteFunctionResultsV1

type ExecuteFunctionResultsV1 struct {
	BaseResponseV1
	Resources []ExecuteFunctionResultV1 `json:"resources"`
}

ExecuteFunctionResultsV1 is the response body when executing a function

type ExecuteFunctionV1

type ExecuteFunctionV1 struct {
	ID       string  `json:"id" description:"ID of the function to execute, in the format 'function_id:version' or 'function_id'."`
	ConfigID string  `json:"config_id" description:"ConfigID for the function to use."`
	Request  Request `` /* 157-byte string literal not displayed */
}

ExecuteFunctionV1 holds request information to execute a function

type ExecuteOperationV1

type ExecuteOperationV1 struct {
	ID       string  `json:"id" description:"ID of the operation to execute, in the format 'operation_id:version' or 'operation_id'."`
	ConfigID string  `json:"config_id" description:"ConfigID for the function to use."`
	Request  Request `` /* 157-byte string literal not displayed */
}

ExecuteOperationV1 holds request information to execute an operation

type Field

type Field struct {
	Name    string      `json:"name"`
	Display string      `json:"display"`
	Kind    string      `json:"kind"`
	Value   interface{} `json:"value"`
}

Field is the metadata and value of a field from a workflow.

type Handler

type Handler func(context.Context, Request) (Response, error)

Handler is the type of function that the authors define to handle incoming requests.

type MetaInfo

type MetaInfo struct {
	QueryTime   float64    `json:"query_time"`
	Paging      *Paging    `json:"pagination,omitempty"`
	Writes      *Resources `json:"writes,omitempty"`
	Attribution string     `json:"powered_by,omitempty"`
	TraceID     string     `json:"trace_id"`
}

MetaInfo metadata for MSA reply

type Paging

type Paging struct {
	Offset int   `json:"offset"`
	Limit  int   `json:"limit"`
	Total  int64 `json:"total"`
}

Paging paging meta

type Params

type Params struct {
	Header http.Header `json:"header,omitempty"`
	Query  url.Values  `json:"query,omitempty"`
}

Params represents the request params

type Request

type Request struct {
	Body        json.RawMessage `json:"body,omitempty"`
	Params      *Params         `json:"params,omitempty"`
	URL         string          `json:"url"`
	Method      string          `json:"method"`
	Context     json.RawMessage `json:"context,omitempty"`
	AccessToken string          `json:"access_token,omitempty"`
}

Request is a default fdk request

func (*Request) Fields

func (r *Request) Fields() []*Field

Fields returns an ordered slice of fields from a workflow.

type Resources

type Resources struct {
	ResourcesEffected int `json:"resources_affected"`
}

Resources reply for effected resources

type Response

type Response struct {
	Body    json.RawMessage     `json:"body,omitempty"`
	Code    int                 `json:"code,omitempty"`
	Headers map[string][]string `json:"headers,omitempty"`
	Errors  []APIError          `json:"errors,omitempty"`
	TraceID string              `json:"trace_id,omitempty"`
}

Response is a base response

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL