Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v0.1.x
* Add support for go1.x lambda runtime
* Fix support for deploying lambda via S3 bucket

# v0.1.2
* Fix property namespaces, function/handler, and include role (#2)

Expand Down
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ source files contained within configured directories.
* Acceptable functions will be defined inline
* S3 storage will be used when inline is unacceptable
* S3 versioning will be used when bucket configured for versioning
* Automatic asset builds (for `java8` runtime targets)
* Automatic asset builds (for `java8` and `go1.x` runtime targets)

## Usage

Expand All @@ -44,14 +44,18 @@ Configuration.new do
end
```

_NOTE: If using the `java8` runtime for lambda functions, `maven` must
be installed with `mvn` being available within the user's PATH._
_NOTE:_
* If using the `java8` runtime for lambda functions, `maven` must
be installed with `mvn` being available within the user's PATH.
* If using the `go1.x` runtime for lambda functions, `golang` and
`zip` utility must be installed with `go` and `zip` being available
within the user's PATH.

### Configuration

#### Lambda function files directory

By default the `sfn-lambda` callback will search the `./lambda` directory
By default, the `sfn-lambda` callback will search the `./lambda` directory
for lambda function files. A custom directory path can be used by modifying
the configuration:

Expand All @@ -65,7 +69,7 @@ end

#### S3 lambda function file storage

By default the `sfn-lambda` callback will use the bucket name provided by
By default, the `sfn-lambda` callback will use the bucket name provided by
the `nesting_bucket` configuration item. This can be customized to use a
different bucket by modifying the configuration:

Expand All @@ -89,13 +93,9 @@ identifier to reference the function. The path structure is as follows:
./lambda/RUNTIME/FUNCTION_NAME.extension
```

The `RUNTIME` defines the runtime used for handling the lambda function. At
the time of writing this, that value can be one of:

* `nodejs`
* `nodejs4.3`
* `java8`
* `python2.7`
The `RUNTIME` defines the runtime used for handling the lambda function.
Please check https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
for the full list.

_NOTE: Runtime values are not validated which allows new runtimes to be used
as they are made available._
Expand Down Expand Up @@ -222,4 +222,4 @@ _NOTE: Maven is required to be installed when using the `java8` runtime_
## Info

* Repository: https://github.com/sparkleformation/sfn-lambda
* IRC: Freenode @ #sparkleformation
* IRC: Freenode @ #sparkleformation
33 changes: 21 additions & 12 deletions lib/sfn-lambda/control.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ class Control

DEFAULTS = {
:INLINE_MAX_SIZE => 4096,
:INLINE_RESTRICTED => ['java8'].freeze,
:INLINE_RESTRICTED => ['java8', 'go1.x'].freeze,
:BUILD_REQUIRED => {
'java8' => {
:build_command => 'mvn package',
:output_directory => './target',
:asset_extension => '.jar'
:asset_extension => 'jar'
}.freeze,
'go1.x' => {
:build_command => 'GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -ldflags="-s -w" -o target/ && zip -j -r target/main.zip target/*',
:output_directory => './target',
:asset_extension => 'zip'
}.freeze
}.freeze
}.freeze
Expand Down Expand Up @@ -86,22 +91,25 @@ def format_content(info)
Smash.new(:raw => File.read(info[:path]))
else
apply_build!(info)
key_name = generate_key_name(info)
io = File.open(info[:path], 'rb')
file = bucket.files.build
file.name = key_name
file.name = generate_key_name(info)
file.body = io
file.save
io.close

version = nil
if(versioning_enabled?)
s3 = callback.api.connection.api_for(:storage)
result = s3.request(
:path => s3.file_path(file),
:path => s3.file_path(file.name),
:endpoint => s3.bucket_endpoint(file.bucket),
:method => :head
)
version = result[:headers][:x_amz_version_id]
end
Smash(:bucket => storage_bucket, :key => key_name, :version => version)

Smash.new(:bucket => bucket.name, :key => file.name, :version => version)
end
end

Expand All @@ -121,12 +129,12 @@ def apply_build!(info)
raise "Failed to build lambda asset for storage! (path: `#{info[:path]}`)"
end
end
file = Dir.glob(File.join(info[:path], build_info[:output_directory], "*.#{build_config[:asset_extension]}")).first
file = Dir.glob(File.join(info[:path], build_info[:output_directory], "*.#{build_info[:asset_extension]}")).first
if(file)
info[:path] = file
true
else
debug "Glob pattern used for build asset detection: `#{File.join(info[:path], build_info[:output_directory], "*.#{build_config[:asset_extension]}")}`"
callback.ui.debug "Glob pattern used for build asset detection: `#{File.join(info[:path], build_info[:output_directory], "*.#{build_info[:asset_extension]}")}`"
raise "Failed to locate generated build asset for storage! (path: `#{info[:path]}`)"
end
else
Expand All @@ -138,7 +146,7 @@ def apply_build!(info)
def bucket
storage_bucket = callback.config.fetch(:lambda, :upload, :bucket, callback.config[:nesting_bucket])
if(storage_bucket)
s3 = api.connection.api_for(:storage)
s3 = callback.api.connection.api_for(:storage)
l_bucket = s3.buckets.get(storage_bucket)
end
unless(l_bucket)
Expand All @@ -150,8 +158,8 @@ def bucket

# @return [TrueClass, FalseClass] bucket has versioning enabled
def versioning_enabled?
unless(@versioned.nil?)
s3 = api.connection.api_for(:storage)
if(@versioned.nil?)
s3 = callback.api.connection.api_for(:storage)
result = s3.request(
:path => '/',
:params => {
Expand All @@ -178,7 +186,8 @@ def generate_key_name(info)
checksum << content
end
end
"sfn.lambda/#{info[:runtime]}/#{File.basename(info[:path])}-#{checksum.base64digest}"
checksum = Base64.urlsafe_encode64(checksum.digest)
"sfn.lambda/#{info[:runtime]}/#{info[:name]}/#{checksum}/#{File.basename(info[:path])}"
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/sfn-lambda/inject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ def _lambda(*fn_args)
new_fn.properties.handler fn_handler
new_fn.properties.runtime lookup[:runtime]
new_fn.properties.function_name fn_function_name || fn_name
new_fn.properties.role fn_role
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving this up so we can set the role even when the lambda function can't be inlined

content = ::SfnLambda.control.format_content(lookup)
if(content[:raw])
new_fn.properties.code.zip_file content[:raw]
new_fn.properties.handler "index.#{fn_handler}"
new_fn.properties.role fn_role
else
new_fn.properties.code.s3_bucket content[:bucket]
new_fn.properties.code.s3_key content[:key]
Expand Down