Class: DPL::Provider::Lambda

Inherits:
DPL::Provider show all
Defined in:
lib/dpl/provider/lambda.rb

Instance Attribute Summary

Attributes inherited from DPL::Provider

#context, #options

Instance Method Summary collapse

Methods inherited from DPL::Provider

apt_get, #check_app, #commit_msg, context, #create_key, #default_text_charset, #default_text_charset?, #deploy, deprecated, #detect_encoding?, #encoding_for, #error, experimental, #initialize, #log, new, npm_g, #option, pip, requires, #run, #setup_git_credentials, #setup_git_ssh, #sha, shell, #user_agent, #warn

Constructor Details

This class inherits a constructor from DPL::Provider

Instance Method Details

#check_authObject



142
143
144
# File 'lib/dpl/provider/lambda.rb', line 142

def check_auth
  log "Using Access Key: #{option(:access_key_id)[-4..-1].rjust(20, '*')}"
end

#cleanupObject



178
179
# File 'lib/dpl/provider/lambda.rb', line 178

def cleanup
end

#create_zip(dest_file_path, src_directory_path, files) ⇒ Object



128
129
130
131
132
133
134
135
136
# File 'lib/dpl/provider/lambda.rb', line 128

def create_zip(dest_file_path, src_directory_path, files)
  Zip::File.open(dest_file_path, Zip::File::CREATE) do |zipfile|
    files.each do |file|
      zipfile.add(file.sub(src_directory_path + File::SEPARATOR, ''), file)
    end
  end

  dest_file_path
end

#default_descriptionObject



158
159
160
# File 'lib/dpl/provider/lambda.rb', line 158

def default_description
  "Deploy build #{context.env['TRAVIS_BUILD_NUMBER']} to AWS Lambda via Travis CI"
end

#default_memory_sizeObject



162
163
164
# File 'lib/dpl/provider/lambda.rb', line 162

def default_memory_size
  128
end

#default_module_nameObject



166
167
168
# File 'lib/dpl/provider/lambda.rb', line 166

def default_module_name
  'index'
end

#default_runtimeObject



150
151
152
# File 'lib/dpl/provider/lambda.rb', line 150

def default_runtime
  'nodejs'
end

#default_timeoutObject



154
155
156
# File 'lib/dpl/provider/lambda.rb', line 154

def default_timeout
  3 # seconds
end

#function_zipObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dpl/provider/lambda.rb', line 94

def function_zip
  target_zip_path = File.absolute_path(options[:zip] || Dir.pwd)
  dest_file_path = output_file_path

  if File.directory?(target_zip_path)
    zip_directory(dest_file_path, target_zip_path)
  elsif File.file?(target_zip_path)
    zip_file(dest_file_path, target_zip_path)
  else
    error('Invalid zip option. If set, must be path to directory, js file, or a zip file.')
  end

  File.new(dest_file_path)
end

#handlerObject



87
88
89
90
91
92
# File 'lib/dpl/provider/lambda.rb', line 87

def handler
  module_name = options[:module_name] || default_module_name
  handler_name = option(:handler_name)

  "#{module_name}.#{handler_name}"
end

#lambdaObject



11
12
13
# File 'lib/dpl/provider/lambda.rb', line 11

def lambda
  @lambda ||= ::Aws::Lambda::Client.new(lambda_options)
end

#lambda_optionsObject



15
16
17
18
19
20
# File 'lib/dpl/provider/lambda.rb', line 15

def lambda_options
  {
    region:      options[:region] || 'us-east-1',
    credentials: ::Aws::Credentials.new(option(:access_key_id), option(:secret_access_key))
  }
end

#needs_key?Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/dpl/provider/lambda.rb', line 138

def needs_key?
  false
end

#output_file_pathObject



146
147
148
# File 'lib/dpl/provider/lambda.rb', line 146

def output_file_path
  @output_file_path ||= '/tmp/' + random_chars(8) + '-lambda.zip'
end

#publishObject



170
171
172
# File 'lib/dpl/provider/lambda.rb', line 170

def publish
  !!options[:publish]
end

#push_appObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/dpl/provider/lambda.rb', line 22

def push_app

  # The original LambdaPreview client supported create/update in one call
  # To keep compatibility we try to fetch the function and then decide
  # whether to update the code or create a new function

  function_name = options[:name] || option(:function_name)

  response = lambda.list_functions

  if response.functions.any? { |function| function.function_name == function_name }

    log "Function #{function_name} already exists, updating."

    # Options defined at
    #   https://docs.aws.amazon.com/sdkforruby/api/Aws/Lambda/Client.html#update_function_configuration-instance_method
    response = lambda.update_function_configuration({
        function_name:  function_name,
        description:    options[:description]    || default_description,
        timeout:        options[:timeout]        || default_timeout,
        memory_size:    options[:memory_size]    || default_memory_size,
        role:           option(:role),
        handler:        handler,
        runtime:        options[:runtime]        || default_runtime,
    })


    log "Updated configuration of function: #{response.function_name}."

    # Options defined at
    #   https://docs.aws.amazon.com/sdkforruby/api/Aws/Lambda/Client.html#update_function_code-instance_method
    response = lambda.update_function_code({
      function_name:  options[:name] || option(:function_name),
      zip_file:       function_zip,
      publish:        publish,
    })

    log "Updated code of function: #{response.function_name}."
  else
    # Options defined at
    #   https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html
    response = lambda.create_function({
      function_name:  options[:name]           || option(:function_name),
      description:    options[:description]    || default_description,
      timeout:        options[:timeout]        || default_timeout,
      memory_size:    options[:memory_size]    || default_memory_size,
      role:           option(:role),
      handler:        handler,
      code: {
        zip_file:     function_zip,
      },
      runtime:        options[:runtime]        || default_runtime,
      publish:        publish,
    })

    log "Created lambda: #{response.function_name}."
  end
rescue ::Aws::Lambda::Errors::ServiceException => exception
  error(exception.message)
rescue ::Aws::Lambda::Errors::InvalidParameterValueException => exception
  error(exception.message)
rescue ::Aws::Lambda::Errors::ResourceNotFoundException => exception
  error(exception.message)
end

#random_chars(count = 8) ⇒ Object



174
175
176
# File 'lib/dpl/provider/lambda.rb', line 174

def random_chars(count=8)
  (36**(count-1) + rand(36**count - 36**(count-1))).to_s(36)
end

#uncleanupObject



181
182
# File 'lib/dpl/provider/lambda.rb', line 181

def uncleanup
end

#zip_directory(dest_file_path, target_directory_path) ⇒ Object



123
124
125
126
# File 'lib/dpl/provider/lambda.rb', line 123

def zip_directory(dest_file_path, target_directory_path)
  files = Dir[File.join(target_directory_path, '**', '**')]
  create_zip(dest_file_path, target_directory_path, files)
end

#zip_file(dest_file_path, target_file_path) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/dpl/provider/lambda.rb', line 109

def zip_file(dest_file_path, target_file_path)
  if File.extname(target_file_path) == '.zip'
    # Just copy it to the destination right away, since it is already a zip.
    FileUtils.cp(target_file_path, dest_file_path)
    dest_file_path
  else
    # Zip up the file.
    src_directory_path = File.dirname(target_file_path)
    files = [ target_file_path ]

    create_zip(dest_file_path, src_directory_path, files)
  end
end