<commit_before>require 'thor'
require 'json'
require 'pp'
require 'parallel'
require 'active_support/core_ext/hash'
require 'json_color'

module Ec2ex
  class CLI < Thor
    include Thor::Actions
    map '-s' => :search
    map '-t' => :search_by_tags
    map '-i' => :search_images
    map '-a' => :aggregate

    class_option :profile, type: :string, default: 'default', required: true, desc: 'name tag'
    class_option :fields, type: :array, default: nil, desc: 'fields'
    def initialize(args = [], options = {}, config = {})
      super(args, options, config)
      @global_options = config[:shell].base.options
      @core = Core.new
      @ec2 = @core.client
      @elb = @core.elb_client
      @logger = @core.logger
    end

    desc 'search', 'search instance'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
    def search(name = options['name'])
      results = @core.instances_hash({ Name: name }, options['running_only'])
      puts_json results
    end

    desc 'search_by_tags', 'search by tags instance'
    option :condition, aliases: '-c', type: :hash, default: {}, desc: 'grouping key'
    option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
    def search_by_tags
      puts_json @core.instances_hash(options['condition'], options['running_only'])
    end

    desc 'reserved', 'reserved instance'
    def reserved
      filter = []
      filter << { name: 'state', values: ['active'] }
      reserved_hash = {}
      @ec2.describe_reserved_instances(filters: filter)[:reserved_instances].each{ |reserved|
        sum = reserved_hash[reserved[:instance_type] + '_' + reserved[:availability_zone]] || 0
        reserved_hash[reserved[:instance_type] + '_' + reserved[:availability_zone]] = sum + reserved[:instance_count]
      }
      list = @core.instances_hash({}, true).select { |instance| instance[:instance_lifecycle].nil? }
      list = list.map{ |_instance|
        ['instance_type', 'placement.availability_zone'].map do |key|
          eval("_instance.#{key} ")
        end.join('_')
      }
      result = {}
      @core.group_count(list).each do |k, v|
        result[k] = { instance_count: v, reserved_count: 0 }
      end
      reserved_hash.each do |k, v|
        hash = result[k] || { instance_count: 0 }
        hash[:reserved_count] = v
        result[k] = hash
      end
      puts_json(result)
    end

    desc 'create_image', 'create image'
    option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
    option :proc, type: :numeric, default: Parallel.processor_count, desc: 'Number of parallel'
    def create_image
      results = @core.instances_hash({ Name: options['name'] }, false)
      Parallel.map(results, in_threads: options['proc']) do |instance|
        begin
          @core.create_image_with_instance(instance)
        rescue => e
          @logger.info "\n#{e.message}\n#{e.backtrace.join("\n")}"
        end
      end
    end

    desc 'deregister_image', 'deregister image'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
    def deregister_image
      @core.get_old_images(options['name'], options['older_than']).each do |image|
        image_id = image[:image_id]
        @logger.info "delete AMI #{image_id}"
        @ec2.deregister_image({image_id: image_id})
        snapshot_ids = image[:block_device_mappings]
            .select{ |block_device_mapping| block_device_mapping[:ebs] != nil }
            .map{ |block_device_mapping| block_device_mapping[:ebs][:snapshot_id] }

        snapshot_ids.each do |snapshot_id|
          @logger.info "delete snapshot #{snapshot_id}"
          @ec2.delete_snapshot({snapshot_id: snapshot_id})
        end
      end
    end

    desc 'deregister_image', 'deregister image'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
    def old_images
      puts_json(@core.get_old_images(options['name'], options['older_than']))<commit_msg>fix, logging ami name with deleting.<commit_after>require 'thor'
require 'json'
require 'pp'
require 'parallel'
require 'active_support/core_ext/hash'
require 'json_color'

module Ec2ex
  class CLI < Thor
    include Thor::Actions
    map '-s' => :search
    map '-t' => :search_by_tags
    map '-i' => :search_images
    map '-a' => :aggregate

    class_option :profile, type: :string, default: 'default', required: true, desc: 'name tag'
    class_option :fields, type: :array, default: nil, desc: 'fields'
    def initialize(args = [], options = {}, config = {})
      super(args, options, config)
      @global_options = config[:shell].base.options
      @core = Core.new
      @ec2 = @core.client
      @elb = @core.elb_client
      @logger = @core.logger
    end

    desc 'search', 'search instance'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
    def search(name = options['name'])
      results = @core.instances_hash({ Name: name }, options['running_only'])
      puts_json results
    end

    desc 'search_by_tags', 'search by tags instance'
    option :condition, aliases: '-c', type: :hash, default: {}, desc: 'grouping key'
    option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
    def search_by_tags
      puts_json @core.instances_hash(options['condition'], options['running_only'])
    end

    desc 'reserved', 'reserved instance'
    def reserved
      filter = []
      filter << { name: 'state', values: ['active'] }
      reserved_hash = {}
      @ec2.describe_reserved_instances(filters: filter)[:reserved_instances].each{ |reserved|
        sum = reserved_hash[reserved[:instance_type] + '_' + reserved[:availability_zone]] || 0
        reserved_hash[reserved[:instance_type] + '_' + reserved[:availability_zone]] = sum + reserved[:instance_count]
      }
      list = @core.instances_hash({}, true).select { |instance| instance[:instance_lifecycle].nil? }
      list = list.map{ |_instance|
        ['instance_type', 'placement.availability_zone'].map do |key|
          eval("_instance.#{key} ")
        end.join('_')
      }
      result = {}
      @core.group_count(list).each do |k, v|
        result[k] = { instance_count: v, reserved_count: 0 }
      end
      reserved_hash.each do |k, v|
        hash = result[k] || { instance_count: 0 }
        hash[:reserved_count] = v
        result[k] = hash
      end
      puts_json(result)
    end

    desc 'create_image', 'create image'
    option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
    option :proc, type: :numeric, default: Parallel.processor_count, desc: 'Number of parallel'
    def create_image
      results = @core.instances_hash({ Name: options['name'] }, false)
      Parallel.map(results, in_threads: options['proc']) do |instance|
        begin
          @core.create_image_with_instance(instance)
        rescue => e
          @logger.info "\n#{e.message}\n#{e.backtrace.join("\n")}"
        end
      end
    end

    desc 'deregister_image', 'deregister image'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
    def deregister_image
      @core.get_old_images(options['name'], options['older_than']).each do |image|
        image_id = image[:image_id]
        @logger.info "delete AMI #{image_id} [#{image[:name]}]"
        @ec2.deregister_image({image_id: image_id})
        snapshot_ids = image[:block_device_mappings]
            .select{ |block_device_mapping| block_device_mapping[:ebs] != nil }
            .map{ |block_device_mapping| block_device_mapping[:ebs][:snapshot_id] }

        snapshot_ids.each do |snapshot_id|
          @logger.info "delete snapshot #{snapshot_id}"
          @ec2.delete_snapshot({snapshot_id: snapshot_id})
        end
      end
    end

    desc 'deregister_image', 'deregister image'
    option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
    option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
    def old_images
      puts_json(@core.get_old_images(options['name'], options['older_than']))
{'fraction_non_alphanumeric': 0.14539617016397202, 'fraction_numerical': 0.0027519779841761265, 'mean_word_length': 3.296551724137931, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '716493', 'n_tokens_mistral': 2759, 'n_tokens_neox': 2716, 'n_words': 693}