class AcornsRdsAuth::CLI

Constants

ENDPOINT_URL

Public Class Methods

new() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 10
def initialize
  @command = :auth
  @options = {
    profile: nil,
    database: nil,
    role: nil,
    timeout: 5,
  }
end
start() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 6
def self.start
  CLI.new.start
end

Public Instance Methods

start() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 20
def start
  parse_options!

  case @command
  when :auth, :authenticate
    do_auth_request!

  else
    raise StandardError.new("Invalid command '#{@command}'")
  end

rescue => err

  STDERR.puts "ERROR:"
  STDERR.puts err.message
  exit(1)
end

Private Instance Methods

credentials() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 112
def credentials
  if @options[:profile]
    Aws::SharedCredentials.new(profile_name: @options[:profile]).credentials
  else
    credentials_provider.credentials
  end
end
credentials_provider() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 108
def credentials_provider
  @credentials_provider ||= Aws::CredentialProviderChain.new.resolve.credentials
end
do_auth_request!() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 40
def do_auth_request!

  envname = @options[:env] || ARGV.shift
  database = @options[:database] || ARGV.shift
  role = @options[:role] || ARGV.shift

  raise OptionParser::MissingArgument.new("env") if envname.nil?
  raise OptionParser::MissingArgument.new("database") if database.nil?

  payload = {
    command: :auth,
    env: envname,
    database: database,
    role: role,
  }

  STDERR.printf("Requesting credentials for '%s' in '%s'", payload[:database], payload[:env])

  if payload[:role]
    STDERR.printf(" (Using role '%s')", payload[:role])
  end

  STDERR.puts ""

  response = do_request(payload)

  # STDERR.puts JSON.pretty_generate(response)
  STDERR.puts "DATABASE USERNAME: #{response[:role]}"
  STDERR.puts ""
  STDERR.puts "PASSWORD TO USE FOR THIS CONNECTION:"

  print response[:token]

end
do_request(payload) click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 128
def do_request(payload)

  raw_payload = JSON.generate(payload)

  signer = Aws::Sigv4::Signer.new(
    service: 'execute-api',
    region: "us-east-1",
    credentials: credentials,
  )

  headers = {
    'content-type' => "application/json",
  }

  signature = signer.sign_request({
    http_method: "POST",
    url: endpoint.to_s,
    headers: headers,
    body: raw_payload,
  })

  http = Net::HTTP.new(endpoint.host, endpoint.port)
  http.open_timeout = @options[:timeout]
  http.read_timeout = @options[:timeout]
  http.use_ssl = true

  request = Net::HTTP::Post.new(endpoint.path)
  request.add_field('user-agent', "AcornsRdsAuth-ruby/#{::AcornsRdsAuth::VERSION}")
  headers.each do |k,v|
    request.add_field(k,v)
  end

  signature.headers.each do |k,v|
    request.add_field(k,v)
  end

  request.body = raw_payload

  res = http.request(request)

  result = JSON.parse(res.body, symbolize_names: true)

  if res.code.to_i == 200
    return result
  else

    # STDERR.puts "ERROR:"

    if result[:Message]
      raise StandardError.new(result[:Message])
    end


    raise StandardError.new("#{res.message}: #{res.body}")
    # exit(1)
  end
end
endpoint() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 124
def endpoint
  @endpoint ||= URI.parse(endpoint_url)
end
endpoint_url() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 120
def endpoint_url
  ENV.fetch("RDS_AUTH_URL", ENDPOINT_URL)
end
options_parser() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 75
def options_parser
  @options_parser ||= OptionParser.new do |opts|
    opts.banner = "Usage: acorns-rds-auth [COMMAND] [options] [...]"
  
    opts.on("-p", "--profile PROFILE", "Specify the AWS profile to use") do |v|
      @options[:profile] = v
      # Aws.config[:profile_name] = v
    end

    opts.on("-e", "--env ENV", "Specify the environment to connect") do |v|
      @options[:env] = v
    end

    opts.on("-d", "--database NAME", "Specify the database to connect") do |v|
      @options[:database] = v
    end

    opts.on("-r", "--role NAME", "Specify the role to connect with. Optional") do |v|
      @options[:role] = v
    end

    opts.on("-h", "--help", "Prints this help") do
      puts opts
      exit
    end
  end
end
parse_options!() click to toggle source
# File lib/acorns-rds-auth/cli.rb, line 103
def parse_options!
  options_parser.parse!
  @command = (ARGV.shift || "auth").downcase.to_sym
end