Module: Foobara::AWS
- Defined in:
- lib/foobara/aws.rb,
lib/foobara/aws/plan.rb,
lib/foobara/aws/check.rb,
lib/foobara/aws/error.rb,
lib/foobara/aws/lambda.rb,
lib/foobara/aws/handler.rb,
lib/foobara/aws/version.rb,
lib/foobara/aws/packager.rb,
lib/foobara/aws/authorizer.rb,
lib/foobara/aws/cdk/service.rb
Overview
Run Foobara commands on AWS Lambda, with the topology read out of the manifest rather than restated in infrastructure code.
Three concerns, deliberately separable because they run in different places:
Foobara::AWS.plan(manifest) WHAT to deploy. Plain data. Needs neither
aws-cdk-lib nor Foobara.
Foobara::AWS::CDK::Service the AWS resources. Synth time; needs
aws-cdk-lib, and no application.
Foobara::AWS::Handler serving a request. Runtime, inside the
Foobara::AWS::Authorizer Lambda; needs neither of the above.
A Lambda bundle requires only "foobara/aws/handler" (or ".../authorizer"), which loads no CDK and no planning code — cold start is on the critical path of every request, and a deployment tool has no business being there.
Defined Under Namespace
Modules: CDK, Lambda Classes: Authorizer, Check, Error, Handler, Packager, Plan, Unit, Unverified
Constant Summary collapse
- DEFAULT_EXCLUDE =
Foobara's own commands — its auth domain and anything else it registers — are infrastructure, not the application, and deploying them is never what anyone means. Matched on the command's full name, which is where that namespace actually shows up.
NOT matched on the organization: an app that declares none is filed under "global_organization", which is most apps, and excluding it would exclude everything.
["Foobara::"].freeze
- VERSION =
"0.2.0"
Class Attribute Summary collapse
-
.caller_builder ⇒ Object
Turns the authorizer's verified claims into whatever the application wants as its caller.
Class Method Summary collapse
-
.current_caller ⇒ Object
WHO IS CALLING, for the duration of one invocation.
-
.current_caller=(value) ⇒ Object
Not an endless def: Ruby does not allow a setter to be one.
-
.plan(manifest, mount: "/run", granularity: :domain, exclude: DEFAULT_EXCLUDE) ⇒ Object
Build a Plan from a Foobara manifest.
Class Attribute Details
.caller_builder ⇒ Object
49 50 51 |
# File 'lib/foobara/aws/handler.rb', line 49 def caller_builder @caller_builder end |
Class Method Details
.current_caller ⇒ Object
WHO IS CALLING, for the duration of one invocation.
Foobara authenticates only commands declaring requires_authentication,
which answers "may this caller in?" but not "who is this?". A command
that is public AND viewer-aware — one that marks your own posts editable
— needs the second without the first, and Foobara has nowhere to put it.
So the handler puts it here, and an application reads it from its connector's authenticator and from any command that needs the viewer as data. A thread-local is not elegant; it is the smallest thing that works until Foobara grows a notion of optional identity.
37 |
# File 'lib/foobara/aws/handler.rb', line 37 def current_caller = Thread.current[:foobara_aws_caller] |
.current_caller=(value) ⇒ Object
Not an endless def: Ruby does not allow a setter to be one.
40 41 42 |
# File 'lib/foobara/aws/handler.rb', line 40 def current_caller=(value) Thread.current[:foobara_aws_caller] = value end |
.plan(manifest, mount: "/run", granularity: :domain, exclude: DEFAULT_EXCLUDE) ⇒ Object
Build a Plan from a Foobara manifest.
manifest the parsed manifest, as served at /manifest by a connector
mount the connector's path prefix ("/run" for the Rack connector)
granularity :domain (default), :organization or :command
A connector's manifest, not Foobara.manifest: requires_authentication
only exists once commands are connected, and it is the field the public
list comes from.
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/foobara/aws/plan.rb', line 75 def plan(manifest, mount: "/run", granularity: :domain, exclude: DEFAULT_EXCLUDE) commands = app_commands(manifest, exclude) units = case granularity when :domain then group_units(commands, "domain", mount) when :organization then group_units(commands, "organization", mount) when :command then command_units(commands, mount) else raise ArgumentError, "unknown granularity #{granularity.inspect}" end Plan.new(mount: mount, granularity: granularity, units: units.sort_by(&:name)) end |