ec2ssh 3.1.0.rc1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/.travis.yml +9 -3
 - data/ChangeLog.md +23 -0
 - data/Gemfile +6 -2
 - data/README.md +27 -24
 - data/Rakefile +3 -0
 - data/bash/ec2ssh.bash +4 -11
 - data/ec2ssh.gemspec +6 -5
 - data/example/example.ec2ssh +2 -2
 - data/fixtures/vcr_cassettes/ec2-instances.yml +178 -0
 - data/lib/ec2ssh/builder.rb +12 -2
 - data/lib/ec2ssh/cli.rb +4 -23
 - data/lib/ec2ssh/command.rb +1 -1
 - data/lib/ec2ssh/command/init.rb +3 -9
 - data/lib/ec2ssh/command/update.rb +0 -5
 - data/lib/ec2ssh/dsl.rb +15 -0
 - data/lib/ec2ssh/ec2_instances.rb +70 -16
 - data/lib/ec2ssh/version.rb +1 -1
 - data/spec/aws_sdk_compatibility_spec.rb +92 -0
 - data/spec/lib/ec2ssh/builder_spec.rb +16 -14
 - data/spec/lib/ec2ssh/command/remove_spec.rb +5 -4
 - data/spec/lib/ec2ssh/command/update_spec.rb +14 -10
 - data/spec/lib/ec2ssh/dsl_spec.rb +44 -11
 - data/spec/lib/ec2ssh/ec2_instances_spec.rb +26 -8
 - data/spec/lib/ec2ssh/ssh_config_spec.rb +2 -0
 - data/spec/spec_helper.rb +5 -1
 - data/zsh/_ec2ssh +8 -50
 - metadata +44 -21
 - data/lib/ec2ssh/command/migrate.rb +0 -34
 - data/lib/ec2ssh/migrator.rb +0 -77
 - data/spec/lib/ec2ssh/command/migrate_spec.rb +0 -111
 - data/spec/lib/ec2ssh/migrator_spec.rb +0 -62
 
    
        data/lib/ec2ssh/cli.rb
    CHANGED
    
    | 
         @@ -2,16 +2,15 @@ require 'thor' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'highline'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'ec2ssh/ssh_config'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'ec2ssh/exceptions'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'ec2ssh/migrator'
         
     | 
| 
       6 
5 
     | 
    
         | 
| 
       7 
6 
     | 
    
         
             
            module Ec2ssh
         
     | 
| 
       8 
7 
     | 
    
         
             
              class CLI < Thor
         
     | 
| 
      
 8 
     | 
    
         
            +
                class_option :path, banner: "/path/to/ssh_config"
         
     | 
| 
       9 
9 
     | 
    
         
             
                class_option :dotfile, banner: '$HOME/.ec2ssh', default: "#{ENV['HOME']}/.ec2ssh"
         
     | 
| 
       10 
     | 
    
         
            -
                class_option :verbose, banner: 'enable debug log',  
     | 
| 
      
 10 
     | 
    
         
            +
                class_option :verbose, banner: 'enable debug log', type: 'boolean'
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                desc 'init', 'Add ec2ssh mark to ssh_config'
         
     | 
| 
       13 
13 
     | 
    
         
             
                def init
         
     | 
| 
       14 
     | 
    
         
            -
                  check_dotfile_version
         
     | 
| 
       15 
14 
     | 
    
         
             
                  command = make_command :init
         
     | 
| 
       16 
15 
     | 
    
         
             
                  command.run
         
     | 
| 
       17 
16 
     | 
    
         
             
                rescue MarkAlreadyExists
         
     | 
| 
         @@ -21,7 +20,6 @@ module Ec2ssh 
     | 
|
| 
       21 
20 
     | 
    
         
             
                desc 'update', 'Update ec2 hosts list in ssh_config'
         
     | 
| 
       22 
21 
     | 
    
         
             
                def update
         
     | 
| 
       23 
22 
     | 
    
         
             
                  check_dotfile_existence
         
     | 
| 
       24 
     | 
    
         
            -
                  check_dotfile_version
         
     | 
| 
       25 
23 
     | 
    
         
             
                  set_aws_logging
         
     | 
| 
       26 
24 
     | 
    
         
             
                  command = make_command :update
         
     | 
| 
       27 
25 
     | 
    
         
             
                  command.run
         
     | 
| 
         @@ -36,7 +34,6 @@ module Ec2ssh 
     | 
|
| 
       36 
34 
     | 
    
         
             
                desc 'remove', 'Remove ec2ssh mark from ssh_config'
         
     | 
| 
       37 
35 
     | 
    
         
             
                def remove
         
     | 
| 
       38 
36 
     | 
    
         
             
                  check_dotfile_existence
         
     | 
| 
       39 
     | 
    
         
            -
                  check_dotfile_version
         
     | 
| 
       40 
37 
     | 
    
         
             
                  command = make_command :remove
         
     | 
| 
       41 
38 
     | 
    
         
             
                  command.run
         
     | 
| 
       42 
39 
     | 
    
         
             
                  green "Removed mark from #{command.ssh_config_path}"
         
     | 
| 
         @@ -44,12 +41,6 @@ module Ec2ssh 
     | 
|
| 
       44 
41 
     | 
    
         
             
                  red "Marker not found in #{command.ssh_config_path}"
         
     | 
| 
       45 
42 
     | 
    
         
             
                end
         
     | 
| 
       46 
43 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                desc 'migrate', 'Migrate dotfile from old versions'
         
     | 
| 
       48 
     | 
    
         
            -
                def migrate
         
     | 
| 
       49 
     | 
    
         
            -
                  command = make_command :migrate
         
     | 
| 
       50 
     | 
    
         
            -
                  command.run
         
     | 
| 
       51 
     | 
    
         
            -
                end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
44 
     | 
    
         
             
                desc 'shellcomp [-]', 'Initialize shell completion for bash/zsh'
         
     | 
| 
       54 
45 
     | 
    
         
             
                def shellcomp(_ = false)
         
     | 
| 
       55 
46 
     | 
    
         
             
                  if args.include?("-")
         
     | 
| 
         @@ -89,16 +80,6 @@ EOS 
     | 
|
| 
       89 
80 
     | 
    
         
             
                end
         
     | 
| 
       90 
81 
     | 
    
         | 
| 
       91 
82 
     | 
    
         
             
                no_tasks do
         
     | 
| 
       92 
     | 
    
         
            -
                  def check_dotfile_version
         
     | 
| 
       93 
     | 
    
         
            -
                    return unless File.exist?(options.dotfile)
         
     | 
| 
       94 
     | 
    
         
            -
                    migrator = Migrator.new options.dotfile
         
     | 
| 
       95 
     | 
    
         
            -
                    if migrator.check_version < '3'
         
     | 
| 
       96 
     | 
    
         
            -
                      red "#{options.dotfile} is old style."
         
     | 
| 
       97 
     | 
    
         
            -
                      red "Try '#{$0} migrate' to migrate to version 3"
         
     | 
| 
       98 
     | 
    
         
            -
                      abort
         
     | 
| 
       99 
     | 
    
         
            -
                    end
         
     | 
| 
       100 
     | 
    
         
            -
                  end
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
83 
     | 
    
         
             
                  def check_dotfile_existence
         
     | 
| 
       103 
84 
     | 
    
         
             
                    unless File.exist?(options.dotfile)
         
     | 
| 
       104 
85 
     | 
    
         
             
                      red "#{options.dotfile} doesn't exist."
         
     | 
| 
         @@ -116,10 +97,10 @@ EOS 
     | 
|
| 
       116 
97 
     | 
    
         
             
                  def set_aws_logging
         
     | 
| 
       117 
98 
     | 
    
         
             
                    if options.verbose
         
     | 
| 
       118 
99 
     | 
    
         
             
                      require 'logger'
         
     | 
| 
       119 
     | 
    
         
            -
                      require 'aws-sdk'
         
     | 
| 
      
 100 
     | 
    
         
            +
                      require 'aws-sdk-core'
         
     | 
| 
       120 
101 
     | 
    
         
             
                      logger = ::Logger.new($stdout)
         
     | 
| 
       121 
102 
     | 
    
         
             
                      logger.level = ::Logger::DEBUG
         
     | 
| 
       122 
     | 
    
         
            -
                      :: 
     | 
| 
      
 103 
     | 
    
         
            +
                      ::Aws.config.update logger: logger
         
     | 
| 
       123 
104 
     | 
    
         
             
                    end
         
     | 
| 
       124 
105 
     | 
    
         
             
                  end
         
     | 
| 
       125 
106 
     | 
    
         | 
    
        data/lib/ec2ssh/command.rb
    CHANGED
    
    
    
        data/lib/ec2ssh/command/init.rb
    CHANGED
    
    | 
         @@ -33,13 +33,7 @@ module Ec2ssh 
     | 
|
| 
       33 
33 
     | 
    
         
             
                  def write_dotfile_example
         
     | 
| 
       34 
34 
     | 
    
         
             
                    example = <<-DOTFILE
         
     | 
| 
       35 
35 
     | 
    
         
             
            path '#{ENV['HOME']}/.ssh/config'
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
              default: {
         
     | 
| 
       38 
     | 
    
         
            -
                access_key_id: ENV['AWS_ACCESS_KEY_ID'],
         
     | 
| 
       39 
     | 
    
         
            -
                secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
         
     | 
| 
       40 
     | 
    
         
            -
              },
         
     | 
| 
       41 
     | 
    
         
            -
              # my_key1: { access_key_id: '...', secret_access_key: '...' }, ...
         
     | 
| 
       42 
     | 
    
         
            -
            )
         
     | 
| 
      
 36 
     | 
    
         
            +
            profiles 'default', 'myprofile'
         
     | 
| 
       43 
37 
     | 
    
         
             
            regions ENV['AWS_REGION'] || ENV['AMAZON_REGION'] || ENV['AWS_DEFAULT_REGION'] || 'us-east-1'
         
     | 
| 
       44 
38 
     | 
    
         
             
            # Enable regions as you like
         
     | 
| 
       45 
39 
     | 
    
         
             
            # regions *%w(ap-northeast-1 ap-southeast-1 ap-southeast-2 eu-west-1 sa-east-1 us-east-1 us-west-1 us-west-2)
         
     | 
| 
         @@ -47,8 +41,8 @@ regions ENV['AWS_REGION'] || ENV['AMAZON_REGION'] || ENV['AWS_DEFAULT_REGION'] | 
     | 
|
| 
       47 
41 
     | 
    
         
             
            # You can use methods of AWS::EC2::Instance.
         
     | 
| 
       48 
42 
     | 
    
         
             
            # See http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Instance.html
         
     | 
| 
       49 
43 
     | 
    
         
             
            host_line <<END
         
     | 
| 
       50 
     | 
    
         
            -
            Host <%=  
     | 
| 
       51 
     | 
    
         
            -
              HostName <%=  
     | 
| 
      
 44 
     | 
    
         
            +
            Host <%= tag('Name') %>.<%= placement.availability_zone %>
         
     | 
| 
      
 45 
     | 
    
         
            +
              HostName <%= public_dns_name || private_ip_address %>
         
     | 
| 
       52 
46 
     | 
    
         
             
            END
         
     | 
| 
       53 
47 
     | 
    
         
             
                    DOTFILE
         
     | 
| 
       54 
48 
     | 
    
         | 
| 
         @@ -3,7 +3,6 @@ require 'ec2ssh/command' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'ec2ssh/ssh_config'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'ec2ssh/builder'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'ec2ssh/dsl'
         
     | 
| 
       6 
     | 
    
         
            -
            require 'ec2ssh/migrator'
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         
             
            module Ec2ssh
         
     | 
| 
       9 
8 
     | 
    
         
             
              module Command
         
     | 
| 
         @@ -30,10 +29,6 @@ module Ec2ssh 
     | 
|
| 
       30 
29 
     | 
    
         
             
                  def dsl
         
     | 
| 
       31 
30 
     | 
    
         
             
                    @dsl ||= Ec2ssh::Dsl::Parser.parse File.read(dotfile_path)
         
     | 
| 
       32 
31 
     | 
    
         
             
                  end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  def migrator
         
     | 
| 
       35 
     | 
    
         
            -
                    @migrator ||= Migrator.new dotfile_path
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
32 
     | 
    
         
             
                end
         
     | 
| 
       38 
33 
     | 
    
         
             
              end
         
     | 
| 
       39 
34 
     | 
    
         
             
            end
         
     | 
    
        data/lib/ec2ssh/dsl.rb
    CHANGED
    
    | 
         @@ -1,14 +1,24 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'ec2ssh/exceptions'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'aws-sdk-core'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Ec2ssh
         
     | 
| 
       4 
5 
     | 
    
         
             
              class Dsl
         
     | 
| 
       5 
6 
     | 
    
         
             
                attr_reader :_result
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
                CREDENTIAL_CLASSES = [Aws::Credentials, Aws::SharedCredentials, Aws::InstanceProfileCredentials, Aws::AssumeRoleCredentials].freeze
         
     | 
| 
      
 9 
     | 
    
         
            +
                private_constant :CREDENTIAL_CLASSES
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       7 
11 
     | 
    
         
             
                def initialize
         
     | 
| 
       8 
12 
     | 
    
         
             
                  @_result = Container.new
         
     | 
| 
       9 
13 
     | 
    
         
             
                end
         
     | 
| 
       10 
14 
     | 
    
         | 
| 
       11 
15 
     | 
    
         
             
                def aws_keys(keys)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  unless keys.all? {|_, v| v.is_a?(Hash) && v.each_value.all? {|c| CREDENTIAL_CLASSES.any?(&c.method(:is_a?)) } }
         
     | 
| 
      
 17 
     | 
    
         
            +
                    raise DotfileValidationError, <<-MSG
         
     | 
| 
      
 18 
     | 
    
         
            +
            Since v4.0, `aws_keys` in the dotfile must be specified regions as a hash key.
         
     | 
| 
      
 19 
     | 
    
         
            +
            See: https://github.com/mirakui/ec2ssh#how-to-upgrade-from-3x
         
     | 
| 
      
 20 
     | 
    
         
            +
                    MSG
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
       12 
22 
     | 
    
         
             
                  @_result.aws_keys = keys
         
     | 
| 
       13 
23 
     | 
    
         
             
                end
         
     | 
| 
       14 
24 
     | 
    
         | 
| 
         @@ -28,6 +38,10 @@ module Ec2ssh 
     | 
|
| 
       28 
38 
     | 
    
         
             
                  @_result.reject = block
         
     | 
| 
       29 
39 
     | 
    
         
             
                end
         
     | 
| 
       30 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                def filters(filters)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @_result.filters = filters
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       31 
45 
     | 
    
         
             
                def path(str)
         
     | 
| 
       32 
46 
     | 
    
         
             
                  @_result.path = str
         
     | 
| 
       33 
47 
     | 
    
         
             
                end
         
     | 
| 
         @@ -38,6 +52,7 @@ module Ec2ssh 
     | 
|
| 
       38 
52 
     | 
    
         
             
                  regions
         
     | 
| 
       39 
53 
     | 
    
         
             
                  host_line
         
     | 
| 
       40 
54 
     | 
    
         
             
                  reject
         
     | 
| 
      
 55 
     | 
    
         
            +
                  filters
         
     | 
| 
       41 
56 
     | 
    
         
             
                  path
         
     | 
| 
       42 
57 
     | 
    
         
             
                ])
         
     | 
| 
       43 
58 
     | 
    
         
             
                end
         
     | 
    
        data/lib/ec2ssh/ec2_instances.rb
    CHANGED
    
    | 
         @@ -1,22 +1,75 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'aws-sdk- 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'aws-sdk-core'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'aws-sdk-ec2'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ec2ssh/exceptions'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            module Ec2ssh
         
     | 
| 
       4 
6 
     | 
    
         
             
              class Ec2Instances
         
     | 
| 
       5 
7 
     | 
    
         
             
                attr_reader :ec2s, :aws_keys
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
      
 9 
     | 
    
         
            +
                class InstanceWrapper
         
     | 
| 
      
 10 
     | 
    
         
            +
                  class TagsWrapper
         
     | 
| 
      
 11 
     | 
    
         
            +
                    def initialize(tags)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      @tags = tags
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    # simulate
         
     | 
| 
      
 16 
     | 
    
         
            +
                    def [](key)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      if key.is_a? ::String
         
     | 
| 
      
 18 
     | 
    
         
            +
                        raise DotfileValidationError, <<-MSG
         
     | 
| 
      
 19 
     | 
    
         
            +
            `tags[String]` syntax in the dotfile has been deleted since v4.0. Use `tag(String)` instead.
         
     | 
| 
      
 20 
     | 
    
         
            +
            See: https://github.com/mirakui/ec2ssh#how-to-upgrade-from-3x
         
     | 
| 
      
 21 
     | 
    
         
            +
                        MSG
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
                      super
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    private
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    def method_missing(name, *args, &block)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      @tags.public_send(name, *args, &block)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    def respond_to_missing?(symbol, include_private)
         
     | 
| 
      
 33 
     | 
    
         
            +
                      @tags.respond_to?(symbol, include_private)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def initialize(ec2_instance)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @ec2_instance = ec2_instance
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @_tags ||= @ec2_instance.tags.each_with_object({}) {|t, h| h[t.key] = t.value }
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def tag(key)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @_tags[key]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def tags
         
     | 
| 
      
 47 
     | 
    
         
            +
                    TagsWrapper.new(super)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  private
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def method_missing(name, *args, &block)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @ec2_instance.public_send(name, *args, &block)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def respond_to_missing?(symbol, include_private)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    @ec2_instance.respond_to?(symbol, include_private)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def initialize(aws_keys, filters)
         
     | 
| 
       8 
62 
     | 
    
         
             
                  @aws_keys = aws_keys
         
     | 
| 
       9 
     | 
    
         
            -
                  @ 
     | 
| 
      
 63 
     | 
    
         
            +
                  @filters = filters
         
     | 
| 
       10 
64 
     | 
    
         
             
                end
         
     | 
| 
       11 
65 
     | 
    
         | 
| 
       12 
66 
     | 
    
         
             
                def make_ec2s
         
     | 
| 
       13 
     | 
    
         
            -
                  AWS.start_memoizing
         
     | 
| 
       14 
67 
     | 
    
         
             
                  _ec2s = {}
         
     | 
| 
       15 
     | 
    
         
            -
                  aws_keys. 
     | 
| 
      
 68 
     | 
    
         
            +
                  aws_keys.each_pair do |name, keys|
         
     | 
| 
       16 
69 
     | 
    
         
             
                    _ec2s[name] = {}
         
     | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
       18 
     | 
    
         
            -
                       
     | 
| 
       19 
     | 
    
         
            -
                      _ec2s[name][region] =  
     | 
| 
      
 70 
     | 
    
         
            +
                    keys.each_pair do |region, key|
         
     | 
| 
      
 71 
     | 
    
         
            +
                      client = Aws::EC2::Client.new region: region, credentials: key
         
     | 
| 
      
 72 
     | 
    
         
            +
                      _ec2s[name][region] = Aws::EC2::Resource.new client: client
         
     | 
| 
       20 
73 
     | 
    
         
             
                    end
         
     | 
| 
       21 
74 
     | 
    
         
             
                  end
         
     | 
| 
       22 
75 
     | 
    
         
             
                  _ec2s
         
     | 
| 
         @@ -27,17 +80,18 @@ module Ec2ssh 
     | 
|
| 
       27 
80 
     | 
    
         
             
                end
         
     | 
| 
       28 
81 
     | 
    
         | 
| 
       29 
82 
     | 
    
         
             
                def instances(key_name)
         
     | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
       31 
     | 
    
         
            -
                    ec2s[key_name][region].instances 
     | 
| 
       32 
     | 
    
         
            -
                       
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 83 
     | 
    
         
            +
                  aws_keys[key_name].each_key.map {|region|
         
     | 
| 
      
 84 
     | 
    
         
            +
                    ec2s[key_name][region].instances(
         
     | 
| 
      
 85 
     | 
    
         
            +
                      filters: @filters
         
     | 
| 
      
 86 
     | 
    
         
            +
                    ).
         
     | 
| 
      
 87 
     | 
    
         
            +
                    map {|ins| InstanceWrapper.new(ins) }.
         
     | 
| 
      
 88 
     | 
    
         
            +
                    sort_by {|ins| ins.tag('Name').to_s }
         
     | 
| 
       35 
89 
     | 
    
         
             
                  }.flatten
         
     | 
| 
       36 
90 
     | 
    
         
             
                end
         
     | 
| 
       37 
91 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                def self.expand_profile_name_to_credential(profile_name)
         
     | 
| 
       39 
     | 
    
         
            -
                   
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
      
 92 
     | 
    
         
            +
                def self.expand_profile_name_to_credential(profile_name, region)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  client = Aws::STS::Client.new(profile: profile_name, region: region)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  client.config.credentials
         
     | 
| 
       41 
95 
     | 
    
         
             
                end
         
     | 
| 
       42 
96 
     | 
    
         
             
              end
         
     | 
| 
       43 
97 
     | 
    
         
             
            end
         
     | 
    
        data/lib/ec2ssh/version.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,92 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'ec2ssh/ec2_instances'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe 'aws-sdk compatibility' do
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:region) { 'us-west-1' }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:root_device) { '/dev/xvda' }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              let!(:ec2_instances) do
         
     | 
| 
      
 9 
     | 
    
         
            +
                VCR.use_cassette('ec2-instances') do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Ec2ssh::Ec2Instances.new(
         
     | 
| 
      
 11 
     | 
    
         
            +
                    {'foo' => {'us-west-1' => Aws::Credentials.new('access_key_id', 'secret_access_key')}},
         
     | 
| 
      
 12 
     | 
    
         
            +
                    [{ name: 'instance-state-name', values: ['running'] }]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ).instances('foo')
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              let(:ins) { ec2_instances.first }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it { expect(ec2_instances.count).to be == 1 }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              it { expect(ins.tag('Name')).to match /.+/ }
         
     | 
| 
      
 22 
     | 
    
         
            +
              it { expect(ins.tag('Role')).to match /.+/ }
         
     | 
| 
      
 23 
     | 
    
         
            +
              it { expect(ins.tags).to match_array([have_attributes(key: 'Name', value: /.+/), have_attributes(key: 'Role', value: /.+/)]) }
         
     | 
| 
      
 24 
     | 
    
         
            +
              it { expect(ins.ami_launch_index).to be == 0 }
         
     | 
| 
      
 25 
     | 
    
         
            +
              it { expect(ins.architecture).to be == 'x86_64' }
         
     | 
| 
      
 26 
     | 
    
         
            +
              it do
         
     | 
| 
      
 27 
     | 
    
         
            +
                expect(ins.block_device_mappings).to match [
         
     | 
| 
      
 28 
     | 
    
         
            +
                  have_attributes(
         
     | 
| 
      
 29 
     | 
    
         
            +
                  device_name: root_device,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  ebs: have_attributes(
         
     | 
| 
      
 31 
     | 
    
         
            +
                    volume_id: /\Avol-\w+\z/,
         
     | 
| 
      
 32 
     | 
    
         
            +
                    status: 'attached',
         
     | 
| 
      
 33 
     | 
    
         
            +
                    attach_time: an_instance_of(Time),
         
     | 
| 
      
 34 
     | 
    
         
            +
                    delete_on_termination: true
         
     | 
| 
      
 35 
     | 
    
         
            +
                  )
         
     | 
| 
      
 36 
     | 
    
         
            +
                )]
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              # it { expect(ins.capacity_reservation_id).to be_nil}
         
     | 
| 
      
 39 
     | 
    
         
            +
              # it { expect(ins.capacity_reservation_specification).to be_nil }
         
     | 
| 
      
 40 
     | 
    
         
            +
              it { expect(ins.classic_address).to be_a(Aws::EC2::ClassicAddress) }
         
     | 
| 
      
 41 
     | 
    
         
            +
              it { expect(ins.client).to be_a(Aws::EC2::Client) }
         
     | 
| 
      
 42 
     | 
    
         
            +
              it { expect(ins.client_token).to match /\A\w{18}\z/ }
         
     | 
| 
      
 43 
     | 
    
         
            +
              # it { expect(ins.cpu_options).to be_nil }
         
     | 
| 
      
 44 
     | 
    
         
            +
              it { expect(ins.ebs_optimized).to be_falsy }
         
     | 
| 
      
 45 
     | 
    
         
            +
              it { expect(ins.elastic_gpu_associations).to be_nil }
         
     | 
| 
      
 46 
     | 
    
         
            +
              # it { expect(ins.elastic_inference_accelerator_associations).to be_nil }
         
     | 
| 
      
 47 
     | 
    
         
            +
              it { expect(ins.ena_support).to be_falsy }
         
     | 
| 
      
 48 
     | 
    
         
            +
              # it { expect(ins.hibernation_options).to be_nil}
         
     | 
| 
      
 49 
     | 
    
         
            +
              it { expect(ins.hypervisor).to be == 'xen' }
         
     | 
| 
      
 50 
     | 
    
         
            +
              it { expect(ins.iam_instance_profile).to have_attributes(arn: /\Aarn:aws:iam::\d+:instance-profile\/[\w\-]+\z/, id: /\A\w{21}\z/) }
         
     | 
| 
      
 51 
     | 
    
         
            +
              it { expect(ins.id).to match /\Ai-\w+\z/ }
         
     | 
| 
      
 52 
     | 
    
         
            +
              it { expect(ins.image).to be_a(Aws::EC2::Image) }
         
     | 
| 
      
 53 
     | 
    
         
            +
              it { expect(ins.image_id).to match /\Aami-\w+\z/ }
         
     | 
| 
      
 54 
     | 
    
         
            +
              it { expect(ins.instance_id).to match /\Ai-\w+\z/ }
         
     | 
| 
      
 55 
     | 
    
         
            +
              it { expect(ins.instance_lifecycle).to be_nil }
         
     | 
| 
      
 56 
     | 
    
         
            +
              it { expect(ins.instance_type).to match /\A[trmci][1248]\.\w+\z/ }
         
     | 
| 
      
 57 
     | 
    
         
            +
              it { expect(ins.kernel_id).to be_nil }
         
     | 
| 
      
 58 
     | 
    
         
            +
              it { expect(ins.key_name).to match /\A.+\.pem\z/ }
         
     | 
| 
      
 59 
     | 
    
         
            +
              it { expect(ins.key_pair).to be_a(Aws::EC2::KeyPairInfo) }
         
     | 
| 
      
 60 
     | 
    
         
            +
              it { expect(ins.launch_time).to be_a(Time) }
         
     | 
| 
      
 61 
     | 
    
         
            +
              # it { expect(ins.licenses).to all have_attributes(license_configuration_arn: '') }
         
     | 
| 
      
 62 
     | 
    
         
            +
              it { expect(ins.monitoring).to have_attributes(state: 'disabled') }
         
     | 
| 
      
 63 
     | 
    
         
            +
              it { expect(ins.network_interfaces).to all match(an_instance_of(Aws::EC2::NetworkInterface)) }
         
     | 
| 
      
 64 
     | 
    
         
            +
              it { expect(ins.placement).to have_attributes(availability_zone: /\A#{region}[a-c]\z/, group_name: '', tenancy: 'default') }
         
     | 
| 
      
 65 
     | 
    
         
            +
              it { expect(ins.placement_group).to be_a(Aws::EC2::PlacementGroup) }
         
     | 
| 
      
 66 
     | 
    
         
            +
              it { expect(ins.platform).to be_nil }
         
     | 
| 
      
 67 
     | 
    
         
            +
              it { expect(ins.private_dns_name).to match /\Aip-[\w\-]+\.#{region}\.compute\.internal\z/ }
         
     | 
| 
      
 68 
     | 
    
         
            +
              it { expect(ins.private_ip_address).to match /\A[\d\.]+\z/ }
         
     | 
| 
      
 69 
     | 
    
         
            +
              it { expect(ins.product_codes).to be == [] }
         
     | 
| 
      
 70 
     | 
    
         
            +
              it { expect(ins.public_dns_name).to match /\Aec2-[\w\-]+\.#{region}\.compute\.amazonaws\.com\z/ }
         
     | 
| 
      
 71 
     | 
    
         
            +
              it { expect(ins.public_ip_address).to match /\A[\d\.]+\z/ }
         
     | 
| 
      
 72 
     | 
    
         
            +
              it { expect(ins.ramdisk_id).to be_nil }
         
     | 
| 
      
 73 
     | 
    
         
            +
              it { expect(ins.root_device_name).to eq root_device }
         
     | 
| 
      
 74 
     | 
    
         
            +
              it { expect(ins.root_device_type).to be == 'ebs' }
         
     | 
| 
      
 75 
     | 
    
         
            +
              it do
         
     | 
| 
      
 76 
     | 
    
         
            +
                expect(ins.security_groups).to all have_attributes(
         
     | 
| 
      
 77 
     | 
    
         
            +
                  group_id: /\Asg-\w+\z/,
         
     | 
| 
      
 78 
     | 
    
         
            +
                  group_name: /\A.+\z/
         
     | 
| 
      
 79 
     | 
    
         
            +
                )
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
              it { expect(ins.source_dest_check).to be true }
         
     | 
| 
      
 82 
     | 
    
         
            +
              it { expect(ins.spot_instance_request_id).to be_nil }
         
     | 
| 
      
 83 
     | 
    
         
            +
              it { expect(ins.sriov_net_support).to be_nil }
         
     | 
| 
      
 84 
     | 
    
         
            +
              it { expect(ins.state).to have_attributes(code: 16, name: 'running') }
         
     | 
| 
      
 85 
     | 
    
         
            +
              it { expect(ins.state_reason).to be_nil }
         
     | 
| 
      
 86 
     | 
    
         
            +
              it { expect(ins.state_transition_reason).to be == '' }
         
     | 
| 
      
 87 
     | 
    
         
            +
              it { expect(ins.subnet).to be_a(Aws::EC2::Subnet) }
         
     | 
| 
      
 88 
     | 
    
         
            +
              it { expect(ins.subnet_id).to match /\Asubnet-\w+\z/ }
         
     | 
| 
      
 89 
     | 
    
         
            +
              it { expect(ins.virtualization_type).to be == 'hvm' }
         
     | 
| 
      
 90 
     | 
    
         
            +
              it { expect(ins.vpc).to be_a(Aws::EC2::Vpc) }
         
     | 
| 
      
 91 
     | 
    
         
            +
              it { expect(ins.vpc_id).to match /\Avpc-\w+\z/ }
         
     | 
| 
      
 92 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -7,10 +7,10 @@ describe Ec2ssh::Builder do 
     | 
|
| 
       7 
7 
     | 
    
         
             
                let(:container) do
         
     | 
| 
       8 
8 
     | 
    
         
             
                  Ec2ssh::Dsl::Container.new.tap do |c|
         
     | 
| 
       9 
9 
     | 
    
         
             
                    c.aws_keys = {
         
     | 
| 
       10 
     | 
    
         
            -
                      key1 
     | 
| 
       11 
     | 
    
         
            -
                      key2 
     | 
| 
      
 10 
     | 
    
         
            +
                      'key1' => { 'us-west-1' => Aws::Credentials.new('KEY1', 'SEC1') },
         
     | 
| 
      
 11 
     | 
    
         
            +
                      'key2' => { 'us-west-1' => Aws::Credentials.new('KEY2', 'SEC2') }
         
     | 
| 
       12 
12 
     | 
    
         
             
                    }
         
     | 
| 
       13 
     | 
    
         
            -
                    c.host_line = "Host <%=  
     | 
| 
      
 13 
     | 
    
         
            +
                    c.host_line = "Host <%= tag('Name') %>"
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         
             
                end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
         @@ -28,12 +28,14 @@ describe Ec2ssh::Builder do 
     | 
|
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                let(:instances) do
         
     | 
| 
       30 
30 
     | 
    
         
             
                  {
         
     | 
| 
       31 
     | 
    
         
            -
                    key1 
     | 
| 
       32 
     | 
    
         
            -
                      double('instance' 
     | 
| 
       33 
     | 
    
         
            -
                      double('instance' 
     | 
| 
       34 
     | 
    
         
            -
                     
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                      double('instance' 
     | 
| 
      
 31 
     | 
    
         
            +
                    'key1' => [
         
     | 
| 
      
 32 
     | 
    
         
            +
                      double('instance').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv1') },
         
     | 
| 
      
 33 
     | 
    
         
            +
                      double('instance').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv2') }
         
     | 
| 
      
 34 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 35 
     | 
    
         
            +
                    'key2' => [
         
     | 
| 
      
 36 
     | 
    
         
            +
                      double('instance').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv3') },
         
     | 
| 
      
 37 
     | 
    
         
            +
                      double('instance').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv4') }
         
     | 
| 
      
 38 
     | 
    
         
            +
                    ]
         
     | 
| 
       37 
39 
     | 
    
         
             
                  }
         
     | 
| 
       38 
40 
     | 
    
         
             
                end
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
         @@ -50,7 +52,7 @@ Host srv4 
     | 
|
| 
       50 
52 
     | 
    
         | 
| 
       51 
53 
     | 
    
         
             
                context 'with #reject' do
         
     | 
| 
       52 
54 
     | 
    
         
             
                  before do
         
     | 
| 
       53 
     | 
    
         
            -
                    container.reject = lambda {|ins| ins. 
     | 
| 
      
 55 
     | 
    
         
            +
                    container.reject = lambda {|ins| ins.tag('Name') == 'srv1' }
         
     | 
| 
       54 
56 
     | 
    
         
             
                  end
         
     | 
| 
       55 
57 
     | 
    
         | 
| 
       56 
58 
     | 
    
         
             
                  it do
         
     | 
| 
         @@ -67,10 +69,10 @@ Host srv4 
     | 
|
| 
       67 
69 
     | 
    
         
             
                context 'checking erb trim_mode' do
         
     | 
| 
       68 
70 
     | 
    
         
             
                  before do
         
     | 
| 
       69 
71 
     | 
    
         
             
                    container.host_line = <<-END
         
     | 
| 
       70 
     | 
    
         
            -
            % if  
     | 
| 
       71 
     | 
    
         
            -
              <%- if  
     | 
| 
       72 
     | 
    
         
            -
            Host <%=  
     | 
| 
       73 
     | 
    
         
            -
              HostName <%=  
     | 
| 
      
 72 
     | 
    
         
            +
            % if tag('Name')
         
     | 
| 
      
 73 
     | 
    
         
            +
              <%- if tag('Name') == 'srv3' -%>
         
     | 
| 
      
 74 
     | 
    
         
            +
            Host <%= tag('Name') %>
         
     | 
| 
      
 75 
     | 
    
         
            +
              HostName <%= tag('Name') %>
         
     | 
| 
       74 
76 
     | 
    
         
             
              <%- end -%>
         
     | 
| 
       75 
77 
     | 
    
         
             
            % end
         
     | 
| 
       76 
78 
     | 
    
         
             
                    END
         
     | 
| 
         @@ -2,6 +2,8 @@ require 'spec_helper' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'ec2ssh/command/remove'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            describe Ec2ssh::Command::Remove do
         
     | 
| 
      
 5 
     | 
    
         
            +
              include FakeFS::SpecHelpers
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       5 
7 
     | 
    
         
             
              describe '#run' do
         
     | 
| 
       6 
8 
     | 
    
         
             
                let(:command) do
         
     | 
| 
       7 
9 
     | 
    
         
             
                  described_class.new(cli).tap do |cmd|
         
     | 
| 
         @@ -17,11 +19,10 @@ describe Ec2ssh::Command::Remove do 
     | 
|
| 
       17 
19 
     | 
    
         | 
| 
       18 
20 
     | 
    
         
             
                let(:dotfile_str) { <<-END }
         
     | 
| 
       19 
21 
     | 
    
         
             
            path '/dotfile'
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            )
         
     | 
| 
      
 22 
     | 
    
         
            +
            profiles 'default'
         
     | 
| 
      
 23 
     | 
    
         
            +
            regions 'us-west-1'
         
     | 
| 
       23 
24 
     | 
    
         
             
            host_line <<EOS
         
     | 
| 
       24 
     | 
    
         
            -
            Host <%=  
     | 
| 
      
 25 
     | 
    
         
            +
            Host <%= tag('Name') %>
         
     | 
| 
       25 
26 
     | 
    
         
             
              HostName <%= private_ip_address %>
         
     | 
| 
       26 
27 
     | 
    
         
             
            EOS
         
     | 
| 
       27 
28 
     | 
    
         
             
                END
         
     |