lib/awskeyring_command.rb in awskeyring-1.8.4 vs lib/awskeyring_command.rb in awskeyring-1.8.5
- old
+ new
@@ -333,11 +333,11 @@
)
puts I18n.t('message.upaccount', account: account)
end
- desc 'token ACCOUNT [ROLE] [MFA]', I18n.t('token_desc')
+ desc 'token ACCOUNT [ROLE] [CODE]', I18n.t('token_desc')
method_option :code, type: :string, aliases: '-c', desc: I18n.t('method_option.code')
method_option :duration, type: :string, aliases: '-d', desc: I18n.t('method_option.duration')
# generate a sessiopn token
def token(account = nil, role = nil, code = nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
account = ask_check(
@@ -428,11 +428,12 @@
end
desc "#{File.basename($PROGRAM_NAME)} CURR PREV", I18n.t('awskeyring_desc'), hide: true
map File.basename($PROGRAM_NAME) => :autocomplete
# autocomplete
- def autocomplete(curr, prev)
+ def autocomplete(curr, prev = nil)
+ curr, prev = fix_args(curr, prev)
comp_line = ENV['COMP_LINE']
comp_point_str = ENV['COMP_POINT']
unless comp_line && comp_point_str
exec_name = File.basename($PROGRAM_NAME)
warn I18n.t('message.awskeyring', path: $PROGRAM_NAME, bin: exec_name)
@@ -446,20 +447,20 @@
puts list.select { |elem| elem.start_with?(curr) }.sort!.join("\n")
end
private
- def age_check_and_get(account:, no_token:)
- cred = Awskeyring.get_valid_creds(account: account, no_token: no_token)
-
- maxage = Awskeyring.key_age
- age = (Time.new - cred[:updated]).div Awskeyring::Awsapi::ONE_DAY
- warn I18n.t('message.age_check', account: account, age: age) unless age < maxage
-
- cred
+ # when a double dash is parsed it is dropped from the args but we need it
+ def fix_args(curr, prev)
+ if prev.nil?
+ [ARGV[1], ARGV[2]]
+ else
+ [curr, prev]
+ end
end
+ # determine the type of completion needed
def comp_type(comp_lines:, prev:)
sub_cmd = sub_command(comp_lines)
comp_idx = comp_lines.rindex(prev)
case prev
@@ -473,21 +474,24 @@
end
[comp_type, sub_cmd]
end
+ # check params for named params or fall back to flags
def param_type(comp_idx, sub_cmd)
- param_list = method(sub_cmd).parameters
+ types = %i[opt req]
+ param_list = method(sub_cmd).parameters.select { |elem| types.include? elem[0] }
if comp_idx.zero?
:command
elsif comp_idx > param_list.length
:flag
else
param_list[comp_idx - 1][1]
end
end
+ # catch the command from prefixes and aliases
def sub_command(comp_lines)
return '' if comp_lines.nil? || comp_lines.length < 2
sub_cmd = comp_lines[1].tr('-', '_')
@@ -496,10 +500,11 @@
return sub_cmds.first if sub_cmds.length == 1
self.class.map[sub_cmd].to_s
end
+ # given a type return the right list for completions
def fetch_auto_resp(comp_type, sub_cmd)
case comp_type
when :command
list_commands
when :account
@@ -515,35 +520,51 @@
else
list_arguments(command: sub_cmd)
end
end
+ # list command names
def list_commands
commands = self.class.all_commands.keys.map { |elem| elem.tr('_', '-') }
commands.reject! { |elem| %w[autocomplete default].include?(elem) }
end
+ # list flags for a command
def list_arguments(command:)
options = self.class.all_commands[command].options.values
exit 1 if options.empty?
options.map(&:aliases).flatten! +
options.map(&:switch_name)
end
+ # add warning about old keys
+ def age_check_and_get(account:, no_token:)
+ cred = Awskeyring.get_valid_creds(account: account, no_token: no_token)
+
+ maxage = Awskeyring.key_age
+ age = (Time.new - cred[:updated]).div Awskeyring::Awsapi::ONE_DAY
+ warn I18n.t('message.age_check', account: account, age: age) unless age < maxage
+
+ cred
+ end
+
+ # print exports from map
def put_env_string(cred)
env_var = Awskeyring::Awsapi.get_env_array(cred)
env_var.each { |var, value| puts "export #{var}=\"#{value}\"" }
Awskeyring::Awsapi::AWS_ENV_VARS.each { |key| puts "unset #{key}" unless env_var.key?(key) }
end
+ # select duration for sts token types
def default_duration(duration, role, code)
duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s if role
duration ||= Awskeyring::Awsapi::TWELVE_HOUR.to_s if code
duration || Awskeyring::Awsapi::ONE_HOUR.to_s
end
+ # ask and validate input values.
def ask_check(existing:, message:, flags: nil, validator: nil, limited_to: nil) # rubocop:disable Metrics/MethodLength
retries ||= 3
begin
value = ask_missing(
existing: existing,
@@ -560,14 +581,16 @@
exit 1
end
value
end
+ # ask for somthinng if its missing.
def ask_missing(existing:, message:, secure: false, optional: false, limited_to: nil)
existing || ask(message: message, secure: secure, optional: optional, limited_to: limited_to).strip
end
+ # ask in different ways
def ask(message:, secure: false, optional: false, limited_to: nil)
if secure
Awskeyring::Input.read_secret("#{message.rjust(20)}: ")
elsif optional
Thor::LineEditor.readline("#{"#{message} (optional)".rjust(20)}: ")
@@ -576,9 +599,10 @@
else
Thor::LineEditor.readline("#{message.rjust(20)}: ")
end
end
+ # undo Bundler env vars
def unbundle
to_delete = ENV.keys.select { |elem| elem.start_with?('BUNDLER_ORIG_') }
bundled_env = to_delete.map { |elem| elem[('BUNDLER_ORIG_'.length)..] }
to_delete << 'BUNDLE_GEMFILE'
bundled_env.each do |env_name|