tools/step_functions
#!/usr/bin/env ruby
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "optimist"
gem "colorize"
end
require "pp"
SUB_COMMANDS = {
"execute" => "Execute an .asl file through the stepfunctions simulator.",
"intrinsic" => "Execute an intrinsic function or JSONPath standalone."
}.freeze
Optimist.options do
banner "Run the aws stepfunctions simulator."
banner ""
banner "Notes:"
banner " This tool requires the stepfunctions simulator to be installed locally and running."
banner " Installation instructions can be found at https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local.html."
banner ""
banner "Commands:"
SUB_COMMANDS.each { |k, v| banner " #{k.ljust(14)}#{v}" }
banner ""
banner " For more help with a specific command use #{$PROGRAM_NAME} <command> --help"
banner ""
banner "Global Options:"
stop_on SUB_COMMANDS.keys
end
cmd = ARGV.shift
Optimist.educate if cmd.nil?
Optimist.die "unknown subcommand #{cmd.inspect}" unless SUB_COMMANDS.include?(cmd)
def aws_stepfunctions(args)
cmd = "aws stepfunctions --endpoint-url http://localhost:8083 #{args}"
puts "** #{cmd}".light_black if ENV["DEBUG"]
output = `#{cmd}`.chomp
output = output.empty? ? {} : JSON.parse(output)
puts output.pretty_inspect.light_black if ENV["DEBUG"]
output
rescue JSON::ParserError => err
warn "ERROR: #{err}".light_red if ENV["DEBUG"]
{}
end
def execute_stepfunction(definition, input)
require "json"
require "shellwords"
begin
state_machine_arn = aws_stepfunctions("create-state-machine --definition #{Shellwords.escape(definition)} --name 'StateMachine' --role-arn 'arn:aws:iam::012345678901:role/DummyRole'")["stateMachineArn"]
exit 1 if state_machine_arn.nil?
input = input ? "--input #{Shellwords.escape(input)}" : ""
execution_arn = aws_stepfunctions("start-execution --state-machine-arn #{state_machine_arn} #{input}")["executionArn"]
exit 1 if execution_arn.nil?
status, output = aws_stepfunctions("describe-execution --execution-arn #{execution_arn}").values_at("status", "output")
if status == "FAILED"
warn "ERROR: Execution failed. See simulator for reason.".light_red
exit 1
end
ensure
aws_stepfunctions("stop-execution --execution-arn #{execution_arn}") if execution_arn
aws_stepfunctions("delete-state-machine --state-machine-arn #{state_machine_arn}") if state_machine_arn
end
puts output if output
end
def execute
opts = Optimist.options do
banner SUB_COMMANDS["execute"]
banner ""
opt :file, "The .asl file to execute", :default => "definition.asl"
opt :input, "Input to the execution", :type => :string
end
definition = File.read(opts[:file]).chomp
execute_stepfunction(definition, opts[:input])
end
def intrinsic
opts = Optimist.options do
banner SUB_COMMANDS["intrinsic"]
banner ""
opt :function, "The intrinsic function or JSONPath to run", :type => :string, :required => true
opt :input, "Input to the execution", :type => :string
end
require "json"
definition = {
"StartAt" => "ExecState",
"States" => {
"ExecState" => {
"Type" => "Pass",
"Parameters" => {"data.$" => opts[:function]},
"OutputPath" => "$.data",
"End" => true
}
}
}.to_json
execute_stepfunction(definition, opts[:input])
end
send(cmd)