require 'slop' require 'rest_client' require 'flydata/api_client' require 'flydata/command_loggable' require 'flydata/source' require 'flydata/command/exclusive_runnable' require 'flydata/preference/data_entry_preference' require 'flydata/util/encryptor' module Flydata module Command class Base include CommandLoggable include ExclusiveRunnable self.exclusive_run_home = FLYDATA_HOME def initialize(options = Slop.new) @api_client = ApiClient.instance @opts = options end attr_reader :opts def flydata; @api_client end def retrieve_data_entries data_entries = flydata.get('/data_entries') unless flydata.response.code == 200 and data_entries raise "Failed to retrieve data_entries" end data_entries.collect do |de| source = Source.create(de) if Flydata::Preference::DataEntryPreference.conf_exists?(de) Flydata::Preference::DataEntryPreference.load_conf(de, source) else Flydata::Preference::DataEntryPreference.filter_data_entry(de, source) de end end end def show_purpose_name begin de = data_entry log_info_stdout("Your current application name is '#{de['purpose_name']}'") rescue RestClient::Unauthorized => e log_warn_stderr("This application is deleted.") rescue AgentInternalError => e case e.code when AgentInternalError::NO_DATA_ENTRY_ERR log_warn_stderr("#{e}") else raise e end end end def data_entry(refresh: false) if @de.nil? || refresh @de = retrieve_data_entries.first end unless @de raise AgentInternalError.new( "No data entry exists. Please set one up on the FlyData Console (#{dashboard_url})", AgentInternalError::NO_DATA_ENTRY_ERR) end @de end def data_port return @data_port if @data_port @data_port = flydata.data_port.get end def redshift_cluster return @redshift_cluster if @redshift_cluster @redshift_cluster = flydata.redshift_cluster.show_default @redshift_cluster['password'] = Flydata::Util::Encryptor.decrypt( @redshift_cluster['encrypted_password'], data_port['key'], 'redshift_cluster password') @redshift_cluster end def source(refresh: false) if @source.nil? || refresh @source = nil @source = Source.create(data_entry(refresh: refresh)) end @source end def register_crontab data_entries = retrieve_data_entries if data_entries.any?{|e| e['log_deletion']} # require on demand to avoid mutual require issue require 'flydata/command/crontab' Flydata::Command::Crontab.new.run end end def dashboard_url "#{flydata.flydata_api_host}/dashboard" end def redshift_console_url "#{flydata.flydata_api_host}/redshift_clusters/query/new" end # print console def newline; puts end def separator(str="=") puts str * 64 end def ask_yes_no(message, default_yes=true) suffix = default_yes ? "(Y/n)" : "(y/n)" prompt = "#{message} #{suffix}: " if opts && opts.yes? # Yes option log_info_stdout("#{prompt}Yes") return true end loop do ans = ask(prompt) return true if default_yes and ans == '' if ans.size > 0 case ans[0].downcase when 'y' log_info("#{prompt}Yes") return true when 'n' log_info("#{prompt}No") return false end end log_warn_stderr(" ! Please answer y[es] or n[o]") newline end end def choose_one(message, prompt, menu_list, value_list=[]) choice = nil value_list = menu_list unless menu_list.size == value_list.size log_info_stdout(message) if message choose do |menu| menu.index = :number menu.index_suffix = ") " menu.select_by = :index menu.prompt = prompt ? prompt : ">> " menu.choices(*menu_list) {|item| choice = value_list[menu_list.index(item)]} end log_info_stdout(" -> #{choice}") choice end def ask_input_table_name input = nil loop do log_info_stdout("Input a table name.") say(">> ") input = gets.strip if input =~ /^[a-zA-Z0-9_]+$/ break else puts "Please enter a valid table name." end end log_info(">> #{input}") input end end end end