class Floaty

Constants

FLOATY_SERVICES

Public Class Methods

check_floaty(data = nil) click to toggle source

This adds some stdout printing here which I was trying to avoid, but I think it makes sense to put it here rather than the main floatyhelper somewhere.

# File lib/floatyhelper/floaty.rb, line 38
def self.check_floaty(data = nil)
  data ||= load_vmfloaty_config

  user = data['user']
  unless user
    puts 'No username found in .vmfloaty.yml.'.yellow
    user = ask('Username: ').chomp
    data['user'] = user
  end
  data['services'] ||= {}
  puts 'No services defined in .vmfloaty.yml.' if data['services'].empty?

  need_token = FLOATY_SERVICES.keys.any? { |k| !data['services'].keys.include?(k) } || data['services'].any? { |_svc, val| val['token'].nil? }
  return unless need_token

  puts 'It appears we need to fetch one or more tokens for the ~/.vmfloaty.yml file. Please enter your Puppet password.'
  password = ask('Password: ') { |q| q.echo = '*' }
  FLOATY_SERVICES.each do |service, info|
    next if data['services'][service] && data['services'][service]['token']

    data['services'][service] ||= {}
    # Kind of silly to call out to curl here.  Replace this with a Net::HTTP call
    output, status = Open3.capture2e("curl -s -X POST -u #{user}:#{password} --url #{info['url']}/token")
    unless status.exitstatus.zero?
      puts "Bad return status from curl to #{info['url']}: #{status.exitstatus}".red
      exit status.exitstatus
    end
    result = JSON.parse(output)
    if result['ok']
      data['services'][service]['type'] = info['type']
      data['services'][service]['url'] = info['url']
      data['services'][service]['token'] = result['token']
      puts "Successfully fetched token for #{service}".green
    else
      puts "Could not get a token from #{service}. Please ensure your username and password are correct.".red
      puts "Result: #{result}".red
      exit 1
    end
  end
  File.write(vmfloatyfile, data.to_yaml)
end
check_tokens() click to toggle source

Make sure all tokens are valid

# File lib/floatyhelper/floaty.rb, line 81
def self.check_tokens
  data = load_vmfloaty_config
  issues = false
  FLOATY_SERVICES.each do |service, info|
    if data['services'].nil? || data['services'][service].nil? || data['services'][service]['token'].nil?
      puts "#{service} service token not found in .vmfloaty.yml".yellow
      issues = true
      next
    end
    # TODO: See what exitcode is when token is bad vs. some other fatal error
    output, _status = Open3.capture2e("/usr/bin/env floaty token status --service #{service}")
    result = parse_floaty_json_output(output)
    next if result['ok']

    puts "Problem checking #{service} token: #{result['reason']}".red
    data['services'][service]['token'] = nil
    if result['reason'].include?('Unparseable')
      # User might have an old URL. Let's make sure to replace it with the latest.
      # Should probably actually check the output for a 503/404 rather than make the
      # assumption here.
      data['services'][service]['url'] = info['url']
    end
    issues = true
  end
  if issues
    check_floaty(data)
  else
    puts 'All tokens valid'.green
  end
end
floaty_cmd(command, ignore_error: false, use_pty: false) click to toggle source
# File lib/floatyhelper/floaty.rb, line 122
def self.floaty_cmd(command, ignore_error: false, use_pty: false)
  check_floaty
  # While we could potentially make a Vmfloaty object and send a command
  # that way, Commander doesn't make it easy.  Parsing floaty's stdout
  # isn't great, but it works for now.
  if use_pty
    output = ''
    status = nil
    IO.popen("/usr/bin/env floaty #{command}", :err => [:child, :out]) do |io|
      while !Process.waitpid(io.pid, Process::WNOHANG)
        line = io.gets
        unless line.nil?
          puts line
          output += line
        end
      end
    end
    # Need to check exit status
    output
  else
    output, status = Open3.capture2e("/usr/bin/env floaty #{command}")
    if !status.exitstatus.zero? && !ignore_error
      puts "Error running 'floaty #{command}': #{output}".red
      exit status.exitstatus
    end
    output
  end
end
load_vmfloaty_config() click to toggle source
# File lib/floatyhelper/floaty.rb, line 27
def self.load_vmfloaty_config
  if File.exist?(vmfloatyfile)
    YAML.safe_load(File.read(vmfloatyfile))
  else
    {}
  end
end
parse_floaty_json_output(output) click to toggle source
# File lib/floatyhelper/floaty.rb, line 112
def self.parse_floaty_json_output(output)
  # Sometimes there will be extra stuff before the hash output,
  # so ignore it until we reach the hash.
  lines = output.split("\n")
  index = lines.index { |l| l[0] == '{' }
  return { 'ok' => false, 'reason' => 'Unparseable response from floaty' } if index.nil?
  output = lines[index..-1].join
  JSON.parse(output.gsub('=>',':'))
end
vmfloatyfile() click to toggle source
# File lib/floatyhelper/floaty.rb, line 23
def self.vmfloatyfile
  "#{Etc.getpwuid.dir}/.vmfloaty.yml"
end