faastruby 0.4.18 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -3
- data/Gemfile.lock +28 -4
- data/README.md +63 -5
- data/faastruby.gemspec +5 -1
- data/lib/faastruby.rb +1 -0
- data/lib/faastruby/api.rb +154 -6
- data/lib/faastruby/base.rb +3 -9
- data/lib/faastruby/cli.rb +39 -12
- data/lib/faastruby/cli/base_command.rb +66 -0
- data/lib/faastruby/cli/commands.rb +122 -59
- data/lib/faastruby/cli/commands/account/base_command.rb +10 -0
- data/lib/faastruby/cli/commands/account/confirm.rb +94 -0
- data/lib/faastruby/cli/commands/account/login.rb +86 -0
- data/lib/faastruby/cli/commands/account/logout.rb +59 -0
- data/lib/faastruby/cli/commands/account/signup.rb +76 -0
- data/lib/faastruby/cli/commands/{function.rb → function/base_command.rb} +2 -11
- data/lib/faastruby/cli/commands/function/build.rb +18 -11
- data/lib/faastruby/cli/commands/function/deploy_to.rb +100 -37
- data/lib/faastruby/cli/commands/function/new.rb +89 -36
- data/lib/faastruby/cli/commands/function/remove_from.rb +21 -6
- data/lib/faastruby/cli/commands/function/run.rb +15 -15
- data/lib/faastruby/cli/commands/function/test.rb +5 -4
- data/lib/faastruby/cli/commands/function/update_context.rb +10 -3
- data/lib/faastruby/cli/commands/function/upgrade.rb +62 -61
- data/lib/faastruby/cli/commands/help.rb +33 -20
- data/lib/faastruby/cli/commands/project/base_command.rb +14 -0
- data/lib/faastruby/cli/commands/project/deploy.rb +114 -0
- data/lib/faastruby/cli/commands/project/down.rb +58 -0
- data/lib/faastruby/cli/commands/project/new.rb +237 -0
- data/lib/faastruby/cli/commands/workspace/cp.rb +107 -0
- data/lib/faastruby/cli/commands/workspace/create.rb +35 -27
- data/lib/faastruby/cli/commands/workspace/destroy.rb +14 -7
- data/lib/faastruby/cli/commands/workspace/list.rb +15 -6
- data/lib/faastruby/cli/commands/workspace/migrate.rb +93 -0
- data/lib/faastruby/cli/commands/workspace/rm.rb +81 -0
- data/lib/faastruby/cli/commands/workspace/update.rb +62 -0
- data/lib/faastruby/cli/credentials.rb +58 -57
- data/lib/faastruby/cli/new_credentials.rb +63 -0
- data/lib/faastruby/cli/package.rb +1 -0
- data/lib/faastruby/cli/template.rb +7 -7
- data/lib/faastruby/local.rb +188 -0
- data/lib/faastruby/local/crystal_runtime.cr +170 -0
- data/lib/faastruby/local/functions.rb +7 -0
- data/lib/faastruby/local/functions/crystal.rb +64 -0
- data/lib/faastruby/local/functions/function.rb +173 -0
- data/lib/faastruby/local/functions/ruby.rb +28 -0
- data/lib/faastruby/local/listeners.rb +5 -0
- data/lib/faastruby/local/listeners/listener.rb +104 -0
- data/lib/faastruby/local/logger.rb +37 -0
- data/lib/faastruby/local/monkey_patch.rb +38 -0
- data/lib/faastruby/local/processors.rb +7 -0
- data/lib/faastruby/local/processors/function.rb +151 -0
- data/lib/faastruby/local/processors/processor.rb +116 -0
- data/lib/faastruby/local/processors/static_file.rb +48 -0
- data/lib/faastruby/local/static_files.rb +5 -0
- data/lib/faastruby/local/static_files/static_file.rb +59 -0
- data/lib/faastruby/server.rb +44 -3
- data/lib/faastruby/server/app.rb +107 -0
- data/lib/faastruby/server/concurrency_controller.rb +50 -50
- data/lib/faastruby/server/config.ru +2 -0
- data/lib/faastruby/server/event.rb +3 -0
- data/lib/faastruby/server/event_hub.rb +7 -6
- data/lib/faastruby/server/local.rb +22 -0
- data/lib/faastruby/server/logger.rb +50 -0
- data/lib/faastruby/server/project_config.rb +44 -0
- data/lib/faastruby/server/puma.rb +4 -0
- data/lib/faastruby/server/response.rb +40 -0
- data/lib/faastruby/server/runner.rb +116 -21
- data/lib/faastruby/server/runner_methods.rb +17 -16
- data/lib/faastruby/server/sentinel.rb +496 -0
- data/lib/faastruby/supported_runtimes.rb +8 -0
- data/lib/faastruby/user.rb +77 -0
- data/lib/faastruby/version.rb +1 -1
- data/lib/faastruby/workspace.rb +36 -3
- data/templates/crystal/example-blank/handler.cr +3 -0
- data/templates/crystal/example/spec/handler_spec.cr +11 -6
- data/templates/public-web/assets/images/background.png +0 -0
- data/templates/public-web/assets/images/ruby.png +0 -0
- data/templates/public-web/assets/javascripts/main.js +1 -0
- data/templates/public-web/assets/stylesheets/main.css +70 -0
- data/templates/public-web/favicon.ico +0 -0
- data/templates/ruby/api-404/handler.rb +6 -0
- data/templates/ruby/api-root/handler.rb +6 -0
- data/templates/ruby/example-blank/handler.rb +0 -23
- data/templates/ruby/web-404/404.html +36 -0
- data/templates/ruby/web-404/handler.rb +3 -0
- data/templates/ruby/web-root/handler.rb +10 -0
- data/templates/ruby/web-root/index.html.erb +37 -0
- data/templates/ruby/web-root/template.rb +13 -0
- metadata +102 -21
- data/exe/faastruby-server +0 -76
- data/lib/faastruby/cli/commands/credentials.rb +0 -11
- data/lib/faastruby/cli/commands/credentials/add.rb +0 -58
- data/lib/faastruby/cli/commands/credentials/list.rb +0 -58
- data/lib/faastruby/cli/commands/workspace.rb +0 -13
- data/lib/faastruby/cli/commands/workspace/deploy.rb +0 -50
- data/templates/crystal/example-blank/README.md +0 -22
- data/templates/crystal/example-blank/spec/handler_spec.cr +0 -8
- data/templates/crystal/example-blank/spec/spec_helper.cr +0 -4
- data/templates/crystal/example-blank/src/handler.cr +0 -25
- data/templates/ruby/example-blank/Gemfile +0 -7
- data/templates/ruby/example-blank/README.md +0 -22
- data/templates/ruby/example-blank/spec/handler_spec.rb +0 -16
- data/templates/ruby/example-blank/spec/spec_helper.rb +0 -3
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'oj'
|
|
2
|
+
require 'faastruby-rpc'
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'sinatra'
|
|
5
|
+
require 'sinatra/multi_route'
|
|
6
|
+
require 'securerandom'
|
|
7
|
+
require 'rouge'
|
|
8
|
+
require 'colorize'
|
|
9
|
+
module FaaStRuby
|
|
10
|
+
|
|
11
|
+
class Server < Sinatra::Base
|
|
12
|
+
include FaaStRuby::Logger::Requests
|
|
13
|
+
set :show_exceptions, true
|
|
14
|
+
set :logging, true
|
|
15
|
+
set :root, SERVER_ROOT
|
|
16
|
+
set :public_folder, FaaStRuby::ProjectConfig.public_dir
|
|
17
|
+
set :static, true
|
|
18
|
+
register Sinatra::MultiRoute
|
|
19
|
+
before do
|
|
20
|
+
cache_control :public, :must_revalidate, :max_age => 1
|
|
21
|
+
end
|
|
22
|
+
route :head, :get, :post, :put, :patch, :delete, '/*' do
|
|
23
|
+
request_uuid = SecureRandom.uuid
|
|
24
|
+
splat = params['splat'][0]
|
|
25
|
+
function_name = resolve_function_name(splat)
|
|
26
|
+
headers = parse_headers(env)
|
|
27
|
+
if headers.has_key?("Faastruby-Rpc")
|
|
28
|
+
body = nil
|
|
29
|
+
rpc_args = parse_body(request.body.read, headers['Content-Type'], request.request_method) || []
|
|
30
|
+
else
|
|
31
|
+
body = parse_body(request.body.read, headers['Content-Type'], request.request_method)
|
|
32
|
+
rpc_args = []
|
|
33
|
+
end
|
|
34
|
+
headers['X-Request-Id'] = request_uuid
|
|
35
|
+
headers['Request-Method'] = request.request_method
|
|
36
|
+
original_request_id = headers['X-Original-Request-Id']
|
|
37
|
+
query_params = parse_query(request.query_string)
|
|
38
|
+
context = Oj.dump(FaaStRuby::ProjectConfig.secrets_for_function(function_name))
|
|
39
|
+
event = FaaStRuby::Event.new(body: body, query_params: query_params, headers: headers, context: context)
|
|
40
|
+
log_request_message(function_name, request, request_uuid, query_params, body, context)
|
|
41
|
+
time, response = FaaStRuby::Runner.new(function_name).call(event, rpc_args)
|
|
42
|
+
status response.status
|
|
43
|
+
headers set_response_headers(response, request_uuid, original_request_id, time)
|
|
44
|
+
response_body, print_body = parse_response(response)
|
|
45
|
+
log_response_message(function_name, time, request_uuid, response, print_body)
|
|
46
|
+
body response_body
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def log_request_message(function_name, request, request_uuid, query_params, body, context)
|
|
50
|
+
puts "[#{function_name}] <- [REQUEST: #{request.request_method} \"#{request.fullpath}\"] request_id=\"#{request_uuid}\" body=\"#{body}\" query_params=#{query_params} headers=#{headers}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def log_response_message(function_name, time, request_uuid, response, print_body)
|
|
54
|
+
puts "[#{function_name}] -> [RESPONSE: #{time}ms] request_id=\"#{request_uuid}\" status=#{response.status} body=#{print_body.inspect} headers=#{response.headers}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def set_response_headers(response, request_uuid, original_request_id = nil, time)
|
|
58
|
+
response.headers['X-Request-Id'] = request_uuid
|
|
59
|
+
response.headers['X-Original-Request-Id'] = original_request_id if original_request_id
|
|
60
|
+
response.headers['X-Execution-time'] = "#{time}ms"
|
|
61
|
+
response.headers
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def parse_response(response)
|
|
65
|
+
return [Base64.urlsafe_decode64(response.body), "Base64(#{response.body})"] if response.binary?
|
|
66
|
+
return [response.body, "#{response.body}"]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def resolve_function_name(splat)
|
|
70
|
+
if splat == ''
|
|
71
|
+
return FaaStRuby::ProjectConfig.root_to
|
|
72
|
+
end
|
|
73
|
+
if !is_a_function?(splat)
|
|
74
|
+
return FaaStRuby::ProjectConfig.catch_all
|
|
75
|
+
end
|
|
76
|
+
return splat
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def is_a_function?(name)
|
|
80
|
+
File.file?("#{FaaStRuby::ProjectConfig.functions_dir}/#{name}/faastruby.yml")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def parse_body(body, content_type, method)
|
|
84
|
+
return nil if method == 'GET'
|
|
85
|
+
return {} if body.nil? && method != 'GET'
|
|
86
|
+
return Oj.load(body) if content_type == 'application/json'
|
|
87
|
+
return body
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def parse_query(query_string)
|
|
91
|
+
hash = {}
|
|
92
|
+
query_string.split('&').each do |param|
|
|
93
|
+
key, value = param.split('=')
|
|
94
|
+
hash[key] = value
|
|
95
|
+
end
|
|
96
|
+
hash
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def parse_headers(env)
|
|
100
|
+
Hash[*env.select {|k,v| k.start_with? 'HTTP_'}
|
|
101
|
+
.collect {|k,v| [k.sub(/^HTTP_/, ''), v]}
|
|
102
|
+
.collect {|k,v| [k.split('_').collect{|a|k == 'DNT' ? k : k.capitalize}.join('-'), v]}
|
|
103
|
+
.sort
|
|
104
|
+
.flatten]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
module FaaStRuby
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def running
|
|
18
|
-
# puts "[ConcurrencyController] [#{name}] Reading runners".red
|
|
19
|
-
# wait
|
|
20
|
-
# puts "[ConcurrencyController] [#{name}] Locking mutex".red
|
|
21
|
-
# @mutex.lock
|
|
22
|
-
@running
|
|
23
|
-
# ensure
|
|
24
|
-
# puts "[ConcurrencyController] [#{name}] Unlocking mutex".red
|
|
25
|
-
# @mutex.unlock
|
|
26
|
-
end
|
|
1
|
+
# module FaaStRuby
|
|
2
|
+
# class ConcurrencyController
|
|
3
|
+
# def self.store
|
|
4
|
+
# @@store ||= {}
|
|
5
|
+
# end
|
|
6
|
+
# attr_accessor :params, :name, :max, :type
|
|
7
|
+
# def initialize(name, max: 1, type:)
|
|
8
|
+
# @type = type
|
|
9
|
+
# @name = name
|
|
10
|
+
# @max = max
|
|
11
|
+
# @running = 0
|
|
12
|
+
# # @mutex = Mutex.new
|
|
13
|
+
# self.class.store[name] = self
|
|
14
|
+
# puts "(ConcurrencyController) Started controller for '#{name}' with max_concurrency = #{@max}".yellow
|
|
15
|
+
# end
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
17
|
+
# def running
|
|
18
|
+
# # puts "[ConcurrencyController] [#{name}] Reading runners".red
|
|
19
|
+
# # wait
|
|
20
|
+
# # puts "[ConcurrencyController] [#{name}] Locking mutex".red
|
|
21
|
+
# # @mutex.lock
|
|
22
|
+
# @running
|
|
23
|
+
# # ensure
|
|
24
|
+
# # puts "[ConcurrencyController] [#{name}] Unlocking mutex".red
|
|
25
|
+
# # @mutex.unlock
|
|
26
|
+
# end
|
|
27
|
+
|
|
28
|
+
# def decr(amount = 1)
|
|
29
|
+
# incr(0 - amount)
|
|
30
|
+
# end
|
|
31
|
+
|
|
32
|
+
# def incr(amount = 1)
|
|
33
|
+
# # puts "[ConcurrencyController] [#{name}] Incr #{amount}".red
|
|
34
|
+
# # wait
|
|
35
|
+
# # puts "[ConcurrencyController] [#{name}] Locking mutex".red
|
|
36
|
+
# # @mutex.lock
|
|
37
|
+
# current = @running + amount
|
|
38
|
+
# return nil if max < current
|
|
39
|
+
# @running += amount
|
|
40
|
+
# # ensure
|
|
41
|
+
# # puts "[ConcurrencyController] [#{name}] Unlocking mutex".red
|
|
42
|
+
# # @mutex.unlock
|
|
43
|
+
# end
|
|
44
|
+
|
|
45
|
+
# # def wait
|
|
46
|
+
# # puts "[ConcurrencyController] [#{name}] Waiting for mutex lock to release".red
|
|
47
|
+
# # while @mutex.locked? do;end
|
|
48
|
+
# # puts "[ConcurrencyController] [#{name}] Mutex released".red
|
|
49
|
+
# # end
|
|
50
|
+
# end
|
|
51
|
+
# end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module FaaStRuby
|
|
2
2
|
class EventHub
|
|
3
|
+
extend FaaStRuby::Logger::System
|
|
3
4
|
@@queue = Queue.new
|
|
4
5
|
def self.queue
|
|
5
6
|
@@queue
|
|
@@ -15,7 +16,7 @@ module FaaStRuby
|
|
|
15
16
|
|
|
16
17
|
def self.load_subscribers
|
|
17
18
|
Dir.glob('*/*/faastruby.yml').each do |file|
|
|
18
|
-
workspace_name, function_name, _ = file.split('/')
|
|
19
|
+
workspace_name, function_name, _ = file.split('/')
|
|
19
20
|
path = "#{workspace_name}/#{function_name}"
|
|
20
21
|
config = YAML.load(File.read(file))
|
|
21
22
|
next unless config['channels'].is_a?(Array)
|
|
@@ -25,8 +26,8 @@ module FaaStRuby
|
|
|
25
26
|
channel.subscribe(path)
|
|
26
27
|
end
|
|
27
28
|
end
|
|
28
|
-
puts "
|
|
29
|
-
puts "
|
|
29
|
+
puts "#{tag} Channel subscriptions: #{EventChannel.channels}"
|
|
30
|
+
puts "#{tag} Please restart the server if you modify channel subscriptions in 'faastruby.yml' for any function."
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def self.listen_for_events!
|
|
@@ -35,16 +36,16 @@ module FaaStRuby
|
|
|
35
36
|
loop do
|
|
36
37
|
encoded_channel, encoded_data = @@queue.pop.split(',')
|
|
37
38
|
channel = EventChannel.new(Base64.urlsafe_decode64(encoded_channel))
|
|
38
|
-
puts "
|
|
39
|
+
puts "#{tag} Event channel=#{channel.name.inspect}"
|
|
39
40
|
channel.subscribers.each do |s|
|
|
40
41
|
subscriber = Subscriber.new(s)
|
|
41
|
-
puts "
|
|
42
|
+
puts "#{tag} Trigger function=#{subscriber.path.inspect} base64_payload=#{encoded_data.inspect}"
|
|
42
43
|
response = subscriber.call(encoded_data)
|
|
43
44
|
puts "[#{subscriber.path}] #=> status=#{response.status} body=#{response.body.inspect} headers=#{Oj.dump response.headers}".light_blue
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
|
-
puts "
|
|
48
|
+
puts "#{tag} Events thread started."
|
|
48
49
|
end
|
|
49
50
|
end
|
|
50
51
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module FaaStRuby
|
|
2
|
+
module Local
|
|
3
|
+
def self.start!(sync: false, deploy_env: 'stage', debug: false)
|
|
4
|
+
Thread.new do
|
|
5
|
+
env = {
|
|
6
|
+
'SYNC' => sync,
|
|
7
|
+
'DEPLOY_ENVIRONMENT' => deploy_env
|
|
8
|
+
}
|
|
9
|
+
cmd = []
|
|
10
|
+
cmd << "SYNC=true" if sync
|
|
11
|
+
cmd << "DEBUG=true" if debug
|
|
12
|
+
cmd << "DEPLOY_ENVIRONMENT=#{deploy_env}"
|
|
13
|
+
cmd << "faastruby watch"
|
|
14
|
+
5.times do
|
|
15
|
+
system(cmd.join(" "))
|
|
16
|
+
sleep 1
|
|
17
|
+
end
|
|
18
|
+
puts "FaaStRuby Local exited. Please press CTRL+C."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module FaaStRuby
|
|
2
|
+
STDOUT_MUTEX = Mutex.new
|
|
3
|
+
module Logger
|
|
4
|
+
module Requests
|
|
5
|
+
|
|
6
|
+
def puts(msg)
|
|
7
|
+
msg = Rouge.highlight(msg, 'ruby', Rouge::Formatters::Terminal256.new(Rouge::Themes::Monokai.new))
|
|
8
|
+
STDOUT_MUTEX.synchronize do
|
|
9
|
+
STDOUT.puts "#{Time.now} | #{msg}"
|
|
10
|
+
STDOUT.puts "---"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.rougify(string, kind)
|
|
15
|
+
Rouge.highlight(string, kind, Rouge::Formatters::Terminal256.new(Rouge::Themes::Monokai.new))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def rougify(string, kind)
|
|
19
|
+
FaaStRuby::Logger.rougify(string, kind)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def tag
|
|
23
|
+
return "(#{self.name.split('::').last})" if self.is_a? Class
|
|
24
|
+
return "(#{self.class.name.split('::').last})"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module System
|
|
30
|
+
def tag
|
|
31
|
+
return "(#{self.name.split('::').last})" if self.is_a? Class
|
|
32
|
+
return "(#{self.class.name.split('::').last})"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.puts(msg)
|
|
36
|
+
STDOUT_MUTEX.synchronize do
|
|
37
|
+
STDOUT.puts "#{Time.now} | #{msg}".yellow
|
|
38
|
+
STDOUT.puts "---".yellow
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def puts(msg)
|
|
43
|
+
STDOUT_MUTEX.synchronize do
|
|
44
|
+
STDOUT.puts "#{Time.now} | #{msg}".yellow
|
|
45
|
+
STDOUT.puts "---".yellow
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module FaaStRuby
|
|
2
|
+
class ProjectConfig
|
|
3
|
+
|
|
4
|
+
def self.public_dir(absolute: true)
|
|
5
|
+
path = "#{SERVER_ROOT}/#{project_config['public_dir'] || 'public'}" if absolute
|
|
6
|
+
path ||= project_config['public_dir'] || 'public'
|
|
7
|
+
path.gsub(/\/$/, '')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.public_dir?
|
|
11
|
+
File.directory? "#{SERVER_ROOT}/#{project_config['public_dir'] || 'public'}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.functions_dir(absolute: true)
|
|
15
|
+
path = "#{SERVER_ROOT}/#{project_config['functions_dir'] || 'functions'}" if absolute
|
|
16
|
+
path ||= project_config['functions_dir'] || 'functions'
|
|
17
|
+
path.gsub(/\/$/, '')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.project_config
|
|
21
|
+
YAML.load(File.read(PROJECT_YAML_FILE))['project']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.root_to
|
|
25
|
+
project_config['root_to'] || 'root'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.catch_all
|
|
29
|
+
project_config['catch_all'] || 'catch-all'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.secrets
|
|
33
|
+
YAML.load(File.read(SECRETS_FILE))['secrets'] || {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.deploy_environment_secrets
|
|
37
|
+
secrets[DEPLOY_ENVIRONMENT] || {}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.secrets_for_function(function_name)
|
|
41
|
+
deploy_environment_secrets[function_name] || {}
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
module FaaStRuby
|
|
2
|
+
require 'base64'
|
|
3
|
+
class InvalidResponseError < StandardError
|
|
4
|
+
def initialize(msg)
|
|
5
|
+
msg = "You must use the method 'render' within your function handler."
|
|
6
|
+
end
|
|
7
|
+
end
|
|
2
8
|
class Response
|
|
9
|
+
def self.error(error)
|
|
10
|
+
new(
|
|
11
|
+
body: error,
|
|
12
|
+
status: 500,
|
|
13
|
+
headers: {'Content-Type' => 'application/json'}
|
|
14
|
+
)
|
|
15
|
+
end
|
|
3
16
|
def self.request_limit_reached(workspace: nil, function: nil)
|
|
4
17
|
body = {'error' => "Concurrent requests limit reached. Please add more runners to the workspace #{workspace}."} if workspace
|
|
5
18
|
# body = {'error' => "Concurrent requests limit reached for function '#{workspace}/#{function}'. Please associate more runners."} if function
|
|
@@ -10,6 +23,19 @@ module FaaStRuby
|
|
|
10
23
|
headers: {'Content-Type' => 'application/json'}
|
|
11
24
|
)
|
|
12
25
|
end
|
|
26
|
+
|
|
27
|
+
def self.from_payload(payload)
|
|
28
|
+
from_json Base64.urlsafe_decode64(payload)
|
|
29
|
+
end
|
|
30
|
+
def self.from_json(json)
|
|
31
|
+
hash = Oj.load(json)
|
|
32
|
+
new(
|
|
33
|
+
body: hash['body'],
|
|
34
|
+
status: hash['status'],
|
|
35
|
+
headers: hash['headers'],
|
|
36
|
+
binary: hash['binary']
|
|
37
|
+
)
|
|
38
|
+
end
|
|
13
39
|
attr_accessor :body, :status, :headers, :binary
|
|
14
40
|
def initialize(body:, status: 200, headers: {}, binary: false)
|
|
15
41
|
@body = body
|
|
@@ -18,6 +44,20 @@ module FaaStRuby
|
|
|
18
44
|
@binary = binary
|
|
19
45
|
end
|
|
20
46
|
|
|
47
|
+
def to_json
|
|
48
|
+
hash = {
|
|
49
|
+
'body' => body,
|
|
50
|
+
'status' => status,
|
|
51
|
+
'headers' => headers,
|
|
52
|
+
'binary' => binary
|
|
53
|
+
}
|
|
54
|
+
Oj.dump(hash)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def payload
|
|
58
|
+
Base64.urlsafe_encode64(to_json, padding: false)
|
|
59
|
+
end
|
|
60
|
+
|
|
21
61
|
def binary?
|
|
22
62
|
@binary
|
|
23
63
|
end
|