lambdaapp

package
v1.62.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package lambdaapp runs sluis as AWS Lambda functions: one binary, one zip, three functions, the role chosen by SLUIS_ROLE (docs/integrations/aws-lambda.md).

http    the issuer and the console behind an API Gateway HTTP API
github  the GitHub roster controller: one pass of one organisation per invocation
slack   the Slack roster controller: one pass of one workspace per invocation

This package assembles each role from the same pieces the Kubernetes process is assembled from (internal/rosterapp and the controllers' apps), and adds the two things Lambda needs: translating the platform's events, and reading secrets from SSM at cold start. It names no cluster, NATS or Valkey client, and cmd/sluis-lambda's import guard keeps it so.

Index

Constants

View Source
const (
	// KindTick is what an EventBridge Scheduler schedule sends, one per target.
	KindTick = "tick"
	// KindRun is what the http function sends when somebody asks for a pass now
	// (internal/port/invoke).
	KindRun = invoke.KindRun
)

The event kinds of a controller function. Both run the same pass; they differ in who asked.

View Source
const (
	// OutcomeRan is a pass that ran to its end.
	OutcomeRan = "ran"
	// OutcomeUnknown is a run-now of a target this controller does not run: the
	// notification was sent to every controller because nobody knew which kind
	// the target is, and the other one ends here, cleanly.
	OutcomeUnknown = "unknown"
	// OutcomeContended is a target another invocation holds the lease of: the
	// pass is its, and this one ends cleanly. It is not a failure, so the
	// platform neither retries it nor counts it as an error.
	OutcomeContended = "contended"
)

The outcomes of a controller invocation.

View Source
const (
	RoleHTTP   = "http"
	RoleGitHub = "github"
	RoleSlack  = "slack"
)

The roles, the values of SLUIS_ROLE.

View Source
const (
	// EnvRole is the function's role: http, github or slack. Required.
	EnvRole = "SLUIS_ROLE"
)

The environment of a function. Everything else is the configuration documents', OpenTelemetry's own OTEL_* variables, or the platform's: SLUIS_CONFIG (config.EnvConfig) names the service document, in the configuration layer mounted at /opt/sluis, and the secrets it names are read from SSM by the `secrets` source it declares.

View Source
const KindExports = "exports"

KindExports is the event an EventBridge Scheduler schedule sends the `http` function to keep the exports (the copies of secrets under /sluis/export/...) current: {"kind":"exports"}. There is no loop to do it on Lambda.

View Source
const KindRefresh = "refresh"

KindRefresh is the event an EventBridge Scheduler schedule sends the `http` function to take a new snapshot of every connected workspace's directory: {"kind":"refresh"}. The Kubernetes server does it on a ticker; there is no loop on Lambda, and a snapshot that is not refreshed stops being authoritative after the freshness window, which sign-in refuses on.

Variables

This section is empty.

Functions

func ParseEvent

func ParseEvent(payload json.RawMessage) (invoke.Event, error)

ParseEvent reads and checks a controller function's event.

func Request

Request makes the http.Request an event describes. The headers arrive lower-cased and the cookies apart from them, and the body is base64 when the gateway says so.

func Response

func Response(status int, header http.Header, body []byte) events.APIGatewayV2HTTPResponse

Response makes an event's response of what a handler wrote. Set-Cookie goes in the response's cookies, as the gateway requires (a header of that name is dropped), the other headers keep their values comma-joined, and the body is base64 when it is not text.

Types

type Controller

type Controller struct {
	// Name is the controller's, in log lines.
	Name string
	// Open assembles the controller.
	Open func(ctx context.Context) (Pass, error)
	Log  *slog.Logger
	// Unknown says an error is the controller not running that target.
	Unknown func(error) bool
}

Controller runs one pass of one target per invocation.

The controller is assembled per invocation and closed at its end, as `sluis tick` does: the audit emitter delivers asynchronously, and a function that is frozen between invocations would hold its queue for hours. What is per process stays per process: the configuration, read and validated at cold start, and the secrets resolved into the environment.

func (*Controller) Handle

func (c *Controller) Handle(ctx context.Context, payload json.RawMessage) (any, error)

Handle implements Handler: payload is {"kind":"tick"|"run","target":"<id>"}.

type ExportsResult added in v1.59.0

type ExportsResult struct {
	Kind string `json:"kind"`
	// Outcome is "ran", "none" (no export is declared) or "failed".
	Outcome   string `json:"outcome"`
	Exports   int    `json:"exports"`
	Done      int    `json:"done"`
	Contended int    `json:"contended"`
	Failed    int    `json:"failed"`
}

ExportsResult is what an exports invocation returns.

type Function

type Function struct {
	Role    string
	Handler Handler
	// Flush sends what telemetry holds; the platform freezes the process when
	// an invocation returns, and a batch waiting for its timer waits for the
	// next invocation.
	Flush func(context.Context)
	// Close releases what the role holds, at shutdown.
	Close func()
}

Function is a role, assembled at cold start and ready to be invoked.

func Open

func Open(ctx context.Context, getenv func(string) string) (*Function, error)

Open assembles the role the environment names. getenv is the process's.

type HTTP

type HTTP struct {
	// contains filtered or unexported fields
}

HTTP serves API Gateway HTTP API events (payload format 2.0) with an http.Handler: the same mux the Kubernetes server serves on its listener.

func NewHTTP

func NewHTTP(handler http.Handler, settle func(), log *slog.Logger) *HTTP

NewHTTP adapts handler. settle may be nil.

func (*HTTP) Handle

func (h *HTTP) Handle(ctx context.Context, payload json.RawMessage) (any, error)

Handle implements Handler: payload is an API Gateway HTTP API event.

func (*HTTP) Serve

Serve runs one request through the handler and returns its response. A request that cannot be made into an http.Request is a 400, and a handler that panics a 500: neither is an error of the invocation, which the platform would retry.

func (*HTTP) WithExports added in v1.59.0

func (h *HTTP) WithExports(run func(context.Context) (ExportsResult, error)) *HTTP

WithExports makes the function answer {"kind":"exports"} events with run.

func (*HTTP) WithRefresh added in v1.61.1

func (h *HTTP) WithRefresh(run func(context.Context) (RefreshResult, error)) *HTTP

WithRefresh makes the function answer {"kind":"refresh"} events with run.

type Handler

type Handler interface {
	Handle(ctx context.Context, payload json.RawMessage) (any, error)
}

Handler is one function's entry point: the platform's event in, a result out.

type Pass

type Pass interface {
	// Pass runs the target's pass under its lease; false, with no error, means
	// another runner holds it.
	Pass(ctx context.Context, target string, unsafeLocal bool) (ran bool, err error)
	// Close flushes what the pass recorded.
	Close() error
}

Pass is one assembled controller, for one invocation.

type RefreshResult added in v1.61.1

type RefreshResult struct {
	Kind       string `json:"kind"`
	Workspaces int    `json:"workspaces"`
	Ran        int    `json:"ran"`
	Contended  int    `json:"contended"`
	Failed     int    `json:"failed"`
}

RefreshResult is what a refresh invocation returns.

type Result

type Result struct {
	Kind    string `json:"kind"`
	Target  string `json:"target"`
	Outcome string `json:"outcome"`
}

Result is what a controller invocation returns.

Jump to

Keyboard shortcuts

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