ec2ssh 3.1.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +8 -0
- data/README.md +25 -23
- data/bash/ec2ssh.bash +2 -2
- data/ec2ssh.gemspec +1 -1
- data/example/example.ec2ssh +2 -2
- data/lib/ec2ssh/builder.rb +12 -2
- data/lib/ec2ssh/cli.rb +1 -21
- 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 +68 -16
- data/lib/ec2ssh/version.rb +1 -1
- data/spec/aws_sdk_compatibility_spec.rb +46 -44
- data/spec/lib/ec2ssh/builder_spec.rb +16 -14
- data/spec/lib/ec2ssh/command/remove_spec.rb +3 -4
- data/spec/lib/ec2ssh/command/update_spec.rb +12 -10
- data/spec/lib/ec2ssh/dsl_spec.rb +44 -11
- data/spec/lib/ec2ssh/ec2_instances_spec.rb +26 -8
- data/zsh/_ec2ssh +0 -7
- metadata +5 -12
- data/lib/ec2ssh/command/migrate.rb +0 -34
- data/lib/ec2ssh/migrator.rb +0 -77
- data/spec/lib/ec2ssh/command/migrate_spec.rb +0 -113
- data/spec/lib/ec2ssh/migrator_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3ea6bd5f9d58e822861e9bcdb35c18df8da80bbc3273a8645483bac6d1d53cf
|
4
|
+
data.tar.gz: d5326d28bfbc630696d42c692dc90e3eae03a0240bece33f6893ac0584f3763d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d22a8bcdc6c4317c09d2b36aee3aaf0a06b5f7412f7e318f40579fb5d6bdeaa3f24d10eaea0a294e253c31ee1e23f2719c5f66bdf20dc46da8931addf471f69c
|
7
|
+
data.tar.gz: 53d4f48c7a7a3dbbbd48d0f0382dfe0715c7af1750b978b9e14183d16adc4bbfaff8872ab65ed2c5ced36debe570682f34c94cb8824735fa800a29ac349f2cea
|
data/ChangeLog.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
# Change Log
|
2
|
+
## 4.0.0
|
3
|
+
* Use aws-sdk v2 and stop using v1 (#44)
|
4
|
+
* Support AssumeRole with `~/.aws/credentials` (#44)
|
5
|
+
* `aws_keys` requires region (#44)
|
6
|
+
Thanks to @yujideveloper
|
7
|
+
* Support `filters` for listing ec2 instances (#43)
|
8
|
+
Thanks to @satotakumi
|
9
|
+
|
2
10
|
## 3.1.1
|
3
11
|
* Fix a bug in `--verbose` option (#41)
|
4
12
|
Thanks to @adamlazz
|
data/README.md
CHANGED
@@ -41,17 +41,22 @@ $ ec2ssh init
|
|
41
41
|
```
|
42
42
|
$ vi ~/.ec2ssh
|
43
43
|
---
|
44
|
-
profiles 'default', 'myprofile'
|
45
|
-
regions 'us-east-1'
|
44
|
+
profiles 'default', 'myprofile', ...
|
45
|
+
regions 'us-east-1', 'ap-northeast-1', ...
|
46
46
|
|
47
47
|
# Ignore unnamed instances
|
48
|
-
reject {|instance| !instance.
|
48
|
+
reject {|instance| !instance.tag('Name') }
|
49
49
|
|
50
|
-
# You can
|
51
|
-
|
50
|
+
# You can specify filters on DescribeInstances (default: lists 'running' instances only)
|
51
|
+
filters([
|
52
|
+
{ name: 'instance-state-name', values: ['running', 'stopped'] }
|
53
|
+
])
|
54
|
+
|
55
|
+
# You can use methods of AWS::EC2::Instance and tag(key) method.
|
56
|
+
# See https://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Instance.html
|
52
57
|
host_line <<END
|
53
|
-
Host <%=
|
54
|
-
HostName <%=
|
58
|
+
Host <%= tag('Name') %>.<%= placement.availability_zone %>
|
59
|
+
HostName <%= public_dns_name || private_ip_address %>
|
55
60
|
END
|
56
61
|
```
|
57
62
|
|
@@ -115,26 +120,23 @@ Host db-server-1.ap-southeast-1
|
|
115
120
|
|
116
121
|
`ec2ssh remove` command removes the mark lines.
|
117
122
|
|
118
|
-
# How to upgrade from
|
119
|
-
|
120
|
-
So you need execute `ec2ssh init` once to create `~/.ec2ssh`, and edit it as you like.
|
121
|
-
|
122
|
-
```
|
123
|
-
$ ec2ssh init
|
124
|
-
$ vi ~/.ec2ssh
|
125
|
-
```
|
126
|
-
|
127
|
-
# How to upgrade from 2.x to 3.x
|
128
|
-
Dotfile (`.ec2ssh`) format has been changed from YAML to Ruby DSL.
|
123
|
+
# How to upgrade from 3.x
|
124
|
+
Dotfile (`.ec2ssh`) format has been changed from 3.x.
|
129
125
|
|
130
|
-
|
126
|
+
* A instance tag access I/F has been changed from `tags['Name']` to `tag('Name')`
|
127
|
+
* `Aws::EC2::Instance` methods have been changed to AWS SDK v2
|
128
|
+
* The `aws_keys` structure have benn changed
|
129
|
+
* `aws_keys[profile_name][region] # => Aws::Credentials`
|
130
|
+
* For example:
|
131
131
|
|
132
132
|
```
|
133
|
-
|
133
|
+
aws_keys(
|
134
|
+
my_prof1: {
|
135
|
+
'ap-northeast-1' => Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
|
136
|
+
}
|
137
|
+
)
|
134
138
|
```
|
135
139
|
|
136
|
-
This command converts your existing `.ec2ssh` file into 3.x style.
|
137
|
-
|
138
140
|
# Notice
|
139
141
|
`ec2ssh` command updates your `.ssh/config` file default. You should make a backup of it.
|
140
142
|
|
@@ -142,4 +144,4 @@ This command converts your existing `.ec2ssh` file into 3.x style.
|
|
142
144
|
Use `zsh/_ec2ssh`.
|
143
145
|
|
144
146
|
# License
|
145
|
-
Copyright (c)
|
147
|
+
Copyright (c) 2019 Issei Naruta. ec2ssh is released under the MIT license.
|
data/bash/ec2ssh.bash
CHANGED
@@ -6,7 +6,7 @@ _ec2ssh() {
|
|
6
6
|
cur=$2
|
7
7
|
prev=$3
|
8
8
|
|
9
|
-
subcmds="help init
|
9
|
+
subcmds="help init remove update version"
|
10
10
|
common_opts="--dotfile --verbose"
|
11
11
|
|
12
12
|
# contextual completion
|
@@ -50,4 +50,4 @@ _ec2ssh() {
|
|
50
50
|
|
51
51
|
}
|
52
52
|
|
53
|
-
complete -F _ec2ssh ec2ssh
|
53
|
+
complete -F _ec2ssh ec2ssh
|
data/ec2ssh.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.rubyforge_project = "ec2ssh"
|
17
17
|
s.add_dependency "thor", "~> 0.14"
|
18
18
|
s.add_dependency "highline", "~> 1.6"
|
19
|
-
s.add_dependency
|
19
|
+
s.add_dependency "aws-sdk", "~> 2"
|
20
20
|
|
21
21
|
s.files = `git ls-files`.split("\n")
|
22
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/example/example.ec2ssh
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
path "#{ENV['HOME']}/.ssh/config"
|
2
2
|
profiles 'default', 'myprofile'
|
3
3
|
regions 'ap-northeast-1', 'us-east-1'
|
4
|
-
reject {|instance| instance.
|
4
|
+
reject {|instance| instance.tag('Name') =~ /.../ }
|
5
5
|
|
6
6
|
host_line <<END
|
7
|
-
Host <%=
|
7
|
+
Host <%= tag('Name') %>
|
8
8
|
HostName <%= private_ip_address %>
|
9
9
|
END
|
data/lib/ec2ssh/builder.rb
CHANGED
@@ -26,19 +26,29 @@ module Ec2ssh
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def ec2s
|
29
|
-
@ec2s ||= Ec2Instances.new aws_keys,
|
29
|
+
@ec2s ||= Ec2Instances.new aws_keys, filters
|
30
30
|
end
|
31
31
|
|
32
32
|
def aws_keys
|
33
33
|
@aws_keys ||= if @container.profiles
|
34
34
|
keys = {}
|
35
35
|
@container.profiles.each do |profile_name|
|
36
|
-
keys[profile_name] =
|
36
|
+
keys[profile_name] = {}
|
37
|
+
@container.regions.each do |region|
|
38
|
+
keys[profile_name][region] = Ec2Instances.expand_profile_name_to_credential profile_name, region
|
39
|
+
end
|
37
40
|
end
|
38
41
|
keys
|
39
42
|
else
|
40
43
|
@container.aws_keys
|
41
44
|
end
|
42
45
|
end
|
46
|
+
|
47
|
+
def filters
|
48
|
+
@filters = @container.filters || [{
|
49
|
+
name: 'instance-state-name',
|
50
|
+
values: ['running']
|
51
|
+
}]
|
52
|
+
end
|
43
53
|
end
|
44
54
|
end
|
data/lib/ec2ssh/cli.rb
CHANGED
@@ -2,7 +2,6 @@ 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
|
@@ -12,7 +11,6 @@ module Ec2ssh
|
|
12
11
|
|
13
12
|
desc 'init', 'Add ec2ssh mark to ssh_config'
|
14
13
|
def init
|
15
|
-
check_dotfile_version
|
16
14
|
command = make_command :init
|
17
15
|
command.run
|
18
16
|
rescue MarkAlreadyExists
|
@@ -22,7 +20,6 @@ module Ec2ssh
|
|
22
20
|
desc 'update', 'Update ec2 hosts list in ssh_config'
|
23
21
|
def update
|
24
22
|
check_dotfile_existence
|
25
|
-
check_dotfile_version
|
26
23
|
set_aws_logging
|
27
24
|
command = make_command :update
|
28
25
|
command.run
|
@@ -37,7 +34,6 @@ module Ec2ssh
|
|
37
34
|
desc 'remove', 'Remove ec2ssh mark from ssh_config'
|
38
35
|
def remove
|
39
36
|
check_dotfile_existence
|
40
|
-
check_dotfile_version
|
41
37
|
command = make_command :remove
|
42
38
|
command.run
|
43
39
|
green "Removed mark from #{command.ssh_config_path}"
|
@@ -45,12 +41,6 @@ module Ec2ssh
|
|
45
41
|
red "Marker not found in #{command.ssh_config_path}"
|
46
42
|
end
|
47
43
|
|
48
|
-
desc 'migrate', 'Migrate dotfile from old versions'
|
49
|
-
def migrate
|
50
|
-
command = make_command :migrate
|
51
|
-
command.run
|
52
|
-
end
|
53
|
-
|
54
44
|
desc 'shellcomp [-]', 'Initialize shell completion for bash/zsh'
|
55
45
|
def shellcomp(_ = false)
|
56
46
|
if args.include?("-")
|
@@ -90,16 +80,6 @@ EOS
|
|
90
80
|
end
|
91
81
|
|
92
82
|
no_tasks do
|
93
|
-
def check_dotfile_version
|
94
|
-
return unless File.exist?(options.dotfile)
|
95
|
-
migrator = Migrator.new options.dotfile
|
96
|
-
if migrator.check_version < '3'
|
97
|
-
red "#{options.dotfile} is old style."
|
98
|
-
red "Try '#{$0} migrate' to migrate to version 3"
|
99
|
-
abort
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
83
|
def check_dotfile_existence
|
104
84
|
unless File.exist?(options.dotfile)
|
105
85
|
red "#{options.dotfile} doesn't exist."
|
@@ -120,7 +100,7 @@ EOS
|
|
120
100
|
require 'aws-sdk'
|
121
101
|
logger = ::Logger.new($stdout)
|
122
102
|
logger.level = ::Logger::DEBUG
|
123
|
-
::
|
103
|
+
::Aws.config.update logger: logger
|
124
104
|
end
|
125
105
|
end
|
126
106
|
|
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'
|
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,73 @@
|
|
1
|
-
require 'aws-sdk
|
1
|
+
require 'aws-sdk'
|
2
2
|
|
3
3
|
module Ec2ssh
|
4
4
|
class Ec2Instances
|
5
5
|
attr_reader :ec2s, :aws_keys
|
6
6
|
|
7
|
-
|
7
|
+
class InstanceWrapper
|
8
|
+
class TagsWrapper
|
9
|
+
def initialize(tags)
|
10
|
+
@tags = tags
|
11
|
+
end
|
12
|
+
|
13
|
+
# simulate
|
14
|
+
def [](key)
|
15
|
+
if key.is_a? ::String
|
16
|
+
raise DotfileValidationError, <<-MSG
|
17
|
+
`tags[String]` syntax in the dotfile has been deleted since v4.0. Use `tag(String)` instead.
|
18
|
+
See: https://github.com/mirakui/ec2ssh#how-to-upgrade-from-3x
|
19
|
+
MSG
|
20
|
+
end
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def method_missing(name, *args, &block)
|
27
|
+
@tags.public_send(name, *args, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to_missing?(symbol, include_private)
|
31
|
+
@tags.respond_to?(symbol, include_private)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(ec2_instance)
|
36
|
+
@ec2_instance = ec2_instance
|
37
|
+
@_tags ||= @ec2_instance.tags.each_with_object({}) {|t, h| h[t.key] = t.value }
|
38
|
+
end
|
39
|
+
|
40
|
+
def tag(key)
|
41
|
+
@_tags[key]
|
42
|
+
end
|
43
|
+
|
44
|
+
def tags
|
45
|
+
TagsWrapper.new(super)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def method_missing(name, *args, &block)
|
51
|
+
@ec2_instance.public_send(name, *args, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def respond_to_missing?(symbol, include_private)
|
55
|
+
@ec2_instance.respond_to?(symbol, include_private)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(aws_keys, filters)
|
8
60
|
@aws_keys = aws_keys
|
9
|
-
@
|
61
|
+
@filters = filters
|
10
62
|
end
|
11
63
|
|
12
64
|
def make_ec2s
|
13
|
-
AWS.start_memoizing
|
14
65
|
_ec2s = {}
|
15
|
-
aws_keys.
|
66
|
+
aws_keys.each_pair do |name, keys|
|
16
67
|
_ec2s[name] = {}
|
17
|
-
|
18
|
-
|
19
|
-
_ec2s[name][region] =
|
68
|
+
keys.each_pair do |region, key|
|
69
|
+
client = Aws::EC2::Client.new region: region, credentials: key
|
70
|
+
_ec2s[name][region] = Aws::EC2::Resource.new client: client
|
20
71
|
end
|
21
72
|
end
|
22
73
|
_ec2s
|
@@ -27,17 +78,18 @@ module Ec2ssh
|
|
27
78
|
end
|
28
79
|
|
29
80
|
def instances(key_name)
|
30
|
-
|
31
|
-
ec2s[key_name][region].instances
|
32
|
-
|
33
|
-
|
34
|
-
|
81
|
+
aws_keys[key_name].each_key.map {|region|
|
82
|
+
ec2s[key_name][region].instances(
|
83
|
+
filters: @filters
|
84
|
+
).
|
85
|
+
map {|ins| InstanceWrapper.new(ins) }.
|
86
|
+
sort_by {|ins| ins.tag('Name').to_s }
|
35
87
|
}.flatten
|
36
88
|
end
|
37
89
|
|
38
|
-
def self.expand_profile_name_to_credential(profile_name)
|
39
|
-
|
40
|
-
|
90
|
+
def self.expand_profile_name_to_credential(profile_name, region)
|
91
|
+
client = Aws::STS::Client.new(profile: profile_name, region: region)
|
92
|
+
client.config.credentials
|
41
93
|
end
|
42
94
|
end
|
43
95
|
end
|
data/lib/ec2ssh/version.rb
CHANGED
@@ -8,8 +8,8 @@ describe 'aws-sdk compatibility' do
|
|
8
8
|
let!(:ec2_instances) do
|
9
9
|
VCR.use_cassette('ec2-instances') do
|
10
10
|
Ec2ssh::Ec2Instances.new(
|
11
|
-
{'foo' => {
|
12
|
-
['
|
11
|
+
{'foo' => {'us-west-1' => Aws::Credentials.new('access_key_id', 'secret_access_key')}},
|
12
|
+
[{ name: 'instance-state-name', values: ['running'] }]
|
13
13
|
).instances('foo')
|
14
14
|
end
|
15
15
|
end
|
@@ -18,54 +18,52 @@ describe 'aws-sdk compatibility' do
|
|
18
18
|
|
19
19
|
it { expect(ec2_instances.count).to be == 1 }
|
20
20
|
|
21
|
-
it { expect(ins.
|
22
|
-
it { expect(ins.
|
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: /.+/)]) }
|
23
24
|
it { expect(ins.ami_launch_index).to be == 0 }
|
24
|
-
it { expect(ins.architecture).to be ==
|
25
|
-
it { expect(ins.attachments.to_h).to match( root_device => an_instance_of(AWS::EC2::Attachment) ) }
|
26
|
-
it { expect(ins.availability_zone).to match /\A#{region}[a-c]\z/ }
|
27
|
-
it { expect(ins.block_device_mappings.to_h).to match( root_device => an_instance_of(AWS::EC2::Attachment) ) }
|
25
|
+
it { expect(ins.architecture).to be == 'x86_64' }
|
28
26
|
it do
|
29
|
-
expect(ins.
|
27
|
+
expect(ins.block_device_mappings).to match [
|
28
|
+
have_attributes(
|
30
29
|
device_name: root_device,
|
31
|
-
ebs:
|
30
|
+
ebs: have_attributes(
|
32
31
|
volume_id: /\Avol-\w+\z/,
|
33
32
|
status: 'attached',
|
34
33
|
attach_time: an_instance_of(Time),
|
35
34
|
delete_on_termination: true
|
36
|
-
|
37
|
-
|
35
|
+
)
|
36
|
+
)]
|
38
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) }
|
39
42
|
it { expect(ins.client_token).to match /\A\w{18}\z/ }
|
40
|
-
it { expect(ins.
|
41
|
-
it { expect(ins.dns_name).to match /\Aec2-[\d\.\-]+\.#{region}\.compute\.amazonaws\.com\z/ }
|
43
|
+
# it { expect(ins.cpu_options).to be_nil }
|
42
44
|
it { expect(ins.ebs_optimized).to be_falsy }
|
43
|
-
it
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it { expect(ins.groups.to_a).to all match(AWS::EC2::SecurityGroup) }
|
50
|
-
it { expect(ins.hypervisor).to be == :xen }
|
51
|
-
it { expect(ins.iam_instance_profile_arn).to match /\Aarn:aws:iam::\d+:instance-profile\/[\w\-]+\z/ }
|
52
|
-
it { expect(ins.iam_instance_profile_id).to match /\A\w{21}\z/ }
|
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/) }
|
53
51
|
it { expect(ins.id).to match /\Ai-\w+\z/ }
|
54
|
-
it { expect(ins.
|
52
|
+
it { expect(ins.identifiers).to match(id: /\Ai-\w+\z/) }
|
53
|
+
it { expect(ins.image).to be_a(Aws::EC2::Image) }
|
55
54
|
it { expect(ins.image_id).to match /\Aami-\w+\z/ }
|
56
55
|
it { expect(ins.instance_id).to match /\Ai-\w+\z/ }
|
57
56
|
it { expect(ins.instance_lifecycle).to be_nil }
|
58
57
|
it { expect(ins.instance_type).to match /\A[trmci][1248]\.\w+\z/ }
|
59
|
-
it { expect(ins.ip_address).to match /\A[\d\.]+\z/ }
|
60
58
|
it { expect(ins.kernel_id).to be_nil }
|
61
59
|
it { expect(ins.key_name).to match /\A.+\.pem\z/ }
|
62
|
-
it { expect(ins.key_pair).to be_a(
|
60
|
+
# it { expect(ins.key_pair).to be_a(Aws::EC2::KeyPairInfo) }
|
63
61
|
it { expect(ins.launch_time).to be_a(Time) }
|
64
|
-
it { expect(ins.
|
65
|
-
it { expect(ins.
|
66
|
-
it { expect(ins.network_interfaces
|
67
|
-
|
68
|
-
it { expect(ins.
|
62
|
+
# it { expect(ins.licenses).to all have_attributes(license_configuration_arn: '') }
|
63
|
+
it { expect(ins.monitoring).to have_attributes(state: 'disabled') }
|
64
|
+
it { expect(ins.network_interfaces).to all match(an_instance_of(Aws::EC2::NetworkInterface)) }
|
65
|
+
it { expect(ins.placement).to have_attributes(availability_zone: /\A#{region}[a-c]\z/, group_name: '', tenancy: 'default') }
|
66
|
+
it { expect(ins.placement_group).to be_a(Aws::EC2::PlacementGroup) }
|
69
67
|
it { expect(ins.platform).to be_nil }
|
70
68
|
it { expect(ins.private_dns_name).to match /\Aip-[\w\-]+\.#{region}\.compute\.internal\z/ }
|
71
69
|
it { expect(ins.private_ip_address).to match /\A[\d\.]+\z/ }
|
@@ -73,19 +71,23 @@ describe 'aws-sdk compatibility' do
|
|
73
71
|
it { expect(ins.public_dns_name).to match /\Aec2-[\w\-]+\.#{region}\.compute\.amazonaws\.com\z/ }
|
74
72
|
it { expect(ins.public_ip_address).to match /\A[\d\.]+\z/ }
|
75
73
|
it { expect(ins.ramdisk_id).to be_nil }
|
76
|
-
it { expect(ins.requester_id).to be_nil }
|
77
|
-
# it { expect(ins.reservation_id).to match /\Ar-\w+\z/ }
|
78
74
|
it { expect(ins.root_device_name).to eq root_device }
|
79
|
-
it { expect(ins.root_device_type).to be ==
|
80
|
-
it
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
75
|
+
it { expect(ins.root_device_type).to be == 'ebs' }
|
76
|
+
it do
|
77
|
+
expect(ins.security_groups).to all have_attributes(
|
78
|
+
group_id: /\Asg-\w+\z/,
|
79
|
+
group_name: /\A.+\z/
|
80
|
+
)
|
81
|
+
end
|
82
|
+
it { expect(ins.source_dest_check).to be true }
|
83
|
+
it { expect(ins.spot_instance_request_id).to be_nil }
|
84
|
+
it { expect(ins.sriov_net_support).to be_nil }
|
85
|
+
it { expect(ins.state).to have_attributes(code: 16, name: 'running') }
|
86
|
+
it { expect(ins.state_reason).to be_nil }
|
87
|
+
it { expect(ins.state_transition_reason).to be == '' }
|
88
|
+
it { expect(ins.subnet).to be_a(Aws::EC2::Subnet) }
|
86
89
|
it { expect(ins.subnet_id).to match /\Asubnet-\w+\z/ }
|
87
|
-
it { expect(ins.virtualization_type).to be ==
|
88
|
-
it { expect(ins.vpc).to be_a(
|
89
|
-
it { expect(ins.vpc?).to be_truthy }
|
90
|
+
it { expect(ins.virtualization_type).to be == 'hvm' }
|
91
|
+
it { expect(ins.vpc).to be_a(Aws::EC2::Vpc) }
|
90
92
|
it { expect(ins.vpc_id).to match /\Avpc-\w+\z/ }
|
91
93
|
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
|
@@ -19,11 +19,10 @@ describe Ec2ssh::Command::Remove do
|
|
19
19
|
|
20
20
|
let(:dotfile_str) { <<-END }
|
21
21
|
path '/dotfile'
|
22
|
-
|
23
|
-
|
24
|
-
)
|
22
|
+
profiles 'default'
|
23
|
+
regions 'us-west-1'
|
25
24
|
host_line <<EOS
|
26
|
-
Host <%=
|
25
|
+
Host <%= tag('Name') %>
|
27
26
|
HostName <%= private_ip_address %>
|
28
27
|
EOS
|
29
28
|
END
|
@@ -9,6 +9,7 @@ describe Ec2ssh::Command::Update do
|
|
9
9
|
let(:command) do
|
10
10
|
described_class.new(cli).tap do |cmd|
|
11
11
|
allow(cmd).to receive(:options).and_return(options)
|
12
|
+
allow(cmd.builder).to receive(:aws_keys) { aws_keys }
|
12
13
|
allow(cmd.builder.ec2s).to receive(:instances) { instances }
|
13
14
|
end
|
14
15
|
end
|
@@ -18,10 +19,13 @@ describe Ec2ssh::Command::Update do
|
|
18
19
|
let(:cli) do
|
19
20
|
double(:cli, options: options, red: nil, yellow: nil, green: nil)
|
20
21
|
end
|
22
|
+
let(:aws_keys) do
|
23
|
+
{'default' => {'us-west-1' => Aws::Credentials.new('access_key_id', 'secret_access_key')}}
|
24
|
+
end
|
21
25
|
let(:instances) do
|
22
26
|
[
|
23
|
-
double('instance',
|
24
|
-
double('instance',
|
27
|
+
double('instance', private_ip_address: '10.0.0.1').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv1') },
|
28
|
+
double('instance', private_ip_address: '10.0.0.2').tap {|m| allow(m).to receive(:tag).with('Name').and_return('srv2') }
|
25
29
|
]
|
26
30
|
end
|
27
31
|
|
@@ -34,11 +38,10 @@ describe Ec2ssh::Command::Update do
|
|
34
38
|
let(:ssh_config_str) { '' }
|
35
39
|
let(:dotfile_str) { <<-END }
|
36
40
|
path '/dotfile'
|
37
|
-
|
38
|
-
|
39
|
-
)
|
41
|
+
profiles 'default'
|
42
|
+
regions 'us-west-1'
|
40
43
|
host_line <<EOS
|
41
|
-
Host <%=
|
44
|
+
Host <%= tag('Name') %>
|
42
45
|
HostName <%= private_ip_address %>
|
43
46
|
EOS
|
44
47
|
END
|
@@ -60,11 +63,10 @@ EOS
|
|
60
63
|
|
61
64
|
let(:dotfile_str) { <<-END }
|
62
65
|
path '/dotfile'
|
63
|
-
|
64
|
-
|
65
|
-
)
|
66
|
+
profiles 'default'
|
67
|
+
regions 'us-west-1'
|
66
68
|
host_line <<EOS
|
67
|
-
Host <%=
|
69
|
+
Host <%= tag('Name') %>
|
68
70
|
HostName <%= private_ip_address %>
|
69
71
|
EOS
|
70
72
|
END
|
data/spec/lib/ec2ssh/dsl_spec.rb
CHANGED
@@ -27,10 +27,9 @@ END
|
|
27
27
|
let(:dsl_str) do
|
28
28
|
<<-END
|
29
29
|
aws_keys(
|
30
|
-
key1
|
31
|
-
key2
|
30
|
+
'key1' => { 'ap-northeast-1' => Aws::Credentials.new('ACCESS_KEY1', 'SECRET1') },
|
31
|
+
'key2' => { 'us-east-1' => Aws::Credentials.new('ACCESS_KEY2', 'SECRET2') }
|
32
32
|
)
|
33
|
-
regions 'ap-northeast-1', 'us-east-1'
|
34
33
|
host_line 'host lines'
|
35
34
|
reject {|instance| instance }
|
36
35
|
path 'path'
|
@@ -40,13 +39,12 @@ END
|
|
40
39
|
subject(:result) { Ec2ssh::Dsl::Parser.parse dsl_str }
|
41
40
|
|
42
41
|
its(:profiles) { should be_nil }
|
43
|
-
|
44
|
-
|
45
|
-
key1
|
46
|
-
key2
|
47
|
-
|
42
|
+
it do
|
43
|
+
expect(result.aws_keys).to match(
|
44
|
+
'key1' => { 'ap-northeast-1' => be_a(Aws::Credentials).and(have_attributes(access_key_id: 'ACCESS_KEY1', secret_access_key: 'SECRET1')) } ,
|
45
|
+
'key2' => { 'us-east-1' => be_a(Aws::Credentials).and(have_attributes(access_key_id: 'ACCESS_KEY2', secret_access_key: 'SECRET2')) }
|
46
|
+
)
|
48
47
|
end
|
49
|
-
its(:regions) { should == ['ap-northeast-1', 'us-east-1'] }
|
50
48
|
its(:host_line) { should == 'host lines' }
|
51
49
|
it { expect(result.reject.call(123)).to eq(123) }
|
52
50
|
its(:path) { should == 'path' }
|
@@ -56,8 +54,8 @@ END
|
|
56
54
|
let(:dsl_str) do
|
57
55
|
<<-END
|
58
56
|
aws_keys(
|
59
|
-
key1
|
60
|
-
key2
|
57
|
+
'key1' => { 'ap-northeast-1' => Aws::Credentials.new('ACCESS_KEY1', 'SECRET1') },
|
58
|
+
'key2' => { 'us-east-1' => Aws::Credentials.new('ACCESS_KEY2', 'SECRET2') }
|
61
59
|
)
|
62
60
|
profiles 'default', 'myprofile'
|
63
61
|
regions 'ap-northeast-1', 'us-east-1'
|
@@ -71,4 +69,39 @@ END
|
|
71
69
|
expect { Ec2ssh::Dsl::Parser.parse dsl_str }.to raise_error Ec2ssh::DotfileValidationError
|
72
70
|
end
|
73
71
|
end
|
72
|
+
|
73
|
+
context 'with old structure aws_keys' do
|
74
|
+
let(:dsl_str) do
|
75
|
+
<<-END
|
76
|
+
aws_keys(
|
77
|
+
key1: { access_key_id: 'ACCESS_KEY1', secret_access_key: 'SECRET1' },
|
78
|
+
key2: { access_key_id: 'ACCESS_KEY2', secret_access_key: 'SECRET2' }
|
79
|
+
)
|
80
|
+
regions 'ap-northeast-1', 'us-east-1'
|
81
|
+
host_line 'host lines'
|
82
|
+
reject {|instance| instance }
|
83
|
+
path 'path'
|
84
|
+
END
|
85
|
+
end
|
86
|
+
|
87
|
+
it { expect { Ec2ssh::Dsl::Parser.parse dsl_str }.to raise_error Ec2ssh::DotfileValidationError }
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with filters' do
|
91
|
+
let(:dsl_str) do
|
92
|
+
<<-END
|
93
|
+
regions 'ap-northeast-1', 'us-east-1'
|
94
|
+
filters [{
|
95
|
+
name: 'instance-state-name',
|
96
|
+
values: ['running', 'stopped']
|
97
|
+
}]
|
98
|
+
END
|
99
|
+
end
|
100
|
+
|
101
|
+
subject(:result) { Ec2ssh::Dsl::Parser.parse dsl_str }
|
102
|
+
|
103
|
+
it do
|
104
|
+
expect(result.filters).to eq([{name:'instance-state-name', values:['running', 'stopped']}])
|
105
|
+
end
|
106
|
+
end
|
74
107
|
end
|
@@ -12,9 +12,11 @@ describe Ec2ssh::Ec2Instances do
|
|
12
12
|
}
|
13
13
|
|
14
14
|
let(:mock) do
|
15
|
-
described_class.new(
|
15
|
+
described_class.new(
|
16
|
+
{key_name => {region => ''}},
|
17
|
+
[{ name: 'instance-state-name', values: ['running'] }]
|
18
|
+
).tap do |e|
|
16
19
|
allow(e).to receive(:ec2s) { ec2s }
|
17
|
-
allow(e).to receive(:regions) { [region] }
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -37,9 +39,9 @@ describe Ec2ssh::Ec2Instances do
|
|
37
39
|
context 'with non-empty names' do
|
38
40
|
let(:mock_instances) {
|
39
41
|
[
|
40
|
-
double('instance', n: 1, tags:
|
41
|
-
double('instance', n: 2, tags:
|
42
|
-
double('instance', n: 3, tags:
|
42
|
+
double('instance', n: 1, tags: [double('tag', key: 'Name', value: 'srvB')]),
|
43
|
+
double('instance', n: 2, tags: [double('tag', key: 'Name', value: 'srvA')]),
|
44
|
+
double('instance', n: 3, tags: [double('tag', key: 'Name', value: 'srvC')])
|
43
45
|
]
|
44
46
|
}
|
45
47
|
|
@@ -52,9 +54,9 @@ describe Ec2ssh::Ec2Instances do
|
|
52
54
|
context 'with names including empty one' do
|
53
55
|
let(:mock_instances) {
|
54
56
|
[
|
55
|
-
double('instance', n: 1, tags:
|
56
|
-
double('instance', n: 2, tags:
|
57
|
-
double('instance', n: 3, tags:
|
57
|
+
double('instance', n: 1, tags: [double('tag', key: 'Name', value: 'srvA')]),
|
58
|
+
double('instance', n: 2, tags: []),
|
59
|
+
double('instance', n: 3, tags: [double('tag', key: 'Name', value: 'srvC')])
|
58
60
|
]
|
59
61
|
}
|
60
62
|
|
@@ -63,6 +65,22 @@ describe Ec2ssh::Ec2Instances do
|
|
63
65
|
expect(result.map {|ins| ins.n}).to match_array([2, 1, 3])
|
64
66
|
end
|
65
67
|
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe Ec2ssh::Ec2Instances::InstanceWrapper do
|
71
|
+
let(:mock_instance) {
|
72
|
+
double('instance', n: 1, tags: [double('tag', key: 'Name', value: 'srvA')])
|
73
|
+
}
|
74
|
+
let(:instance) { described_class.new(mock_instance) }
|
66
75
|
|
76
|
+
describe '#tag' do
|
77
|
+
it { expect(instance.tag('Name')).to eq 'srvA' }
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#tags' do
|
81
|
+
it { expect(instance.tags).to match_array(have_attributes(key: 'Name', value: 'srvA')) }
|
82
|
+
it { expect(instance.tags[0]).to have_attributes(key: 'Name', value: 'srvA') }
|
83
|
+
it { expect { instance.tags['Name'] }.to raise_error Ec2ssh::DotfileValidationError }
|
84
|
+
end
|
67
85
|
end
|
68
86
|
end
|
data/zsh/_ec2ssh
CHANGED
@@ -7,12 +7,6 @@ _ec2ssh-init() {
|
|
7
7
|
return $ret
|
8
8
|
}
|
9
9
|
|
10
|
-
_ec2ssh-migrate() {
|
11
|
-
local ret
|
12
|
-
_call_function ret __ec2ssh_noarg_cmd
|
13
|
-
return $ret
|
14
|
-
}
|
15
|
-
|
16
10
|
_ec2ssh-remove() {
|
17
11
|
local ret
|
18
12
|
_call_function ret __ec2ssh_noarg_cmd
|
@@ -80,7 +74,6 @@ _ec2ssh_commands() {
|
|
80
74
|
_values 'command' \
|
81
75
|
'help[Describe available commands or one specific command]' \
|
82
76
|
'init[Add ec2ssh mark to ssh_config]' \
|
83
|
-
'migrate[Migrate dotfile from old versions]' \
|
84
77
|
'remove[Remove ec2ssh mark from ssh_config]' \
|
85
78
|
'update[Update ec2 hosts list in ssh_config]' \
|
86
79
|
'version[Show version]'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ec2ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Issei Naruta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2'
|
55
55
|
description: ec2ssh is a ssh_config manager for AWS EC2
|
56
56
|
email:
|
57
57
|
- mimitako@gmail.com
|
@@ -79,24 +79,20 @@ files:
|
|
79
79
|
- lib/ec2ssh/cli.rb
|
80
80
|
- lib/ec2ssh/command.rb
|
81
81
|
- lib/ec2ssh/command/init.rb
|
82
|
-
- lib/ec2ssh/command/migrate.rb
|
83
82
|
- lib/ec2ssh/command/remove.rb
|
84
83
|
- lib/ec2ssh/command/update.rb
|
85
84
|
- lib/ec2ssh/dsl.rb
|
86
85
|
- lib/ec2ssh/ec2_instances.rb
|
87
86
|
- lib/ec2ssh/exceptions.rb
|
88
|
-
- lib/ec2ssh/migrator.rb
|
89
87
|
- lib/ec2ssh/ssh_config.rb
|
90
88
|
- lib/ec2ssh/version.rb
|
91
89
|
- spec/aws_sdk_compatibility_spec.rb
|
92
90
|
- spec/lib/ec2ssh/builder_spec.rb
|
93
91
|
- spec/lib/ec2ssh/command/init_spec.rb
|
94
|
-
- spec/lib/ec2ssh/command/migrate_spec.rb
|
95
92
|
- spec/lib/ec2ssh/command/remove_spec.rb
|
96
93
|
- spec/lib/ec2ssh/command/update_spec.rb
|
97
94
|
- spec/lib/ec2ssh/dsl_spec.rb
|
98
95
|
- spec/lib/ec2ssh/ec2_instances_spec.rb
|
99
|
-
- spec/lib/ec2ssh/migrator_spec.rb
|
100
96
|
- spec/lib/ec2ssh/ssh_config_spec.rb
|
101
97
|
- spec/spec_helper.rb
|
102
98
|
- zsh/_ec2ssh
|
@@ -118,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
114
|
- !ruby/object:Gem::Version
|
119
115
|
version: '0'
|
120
116
|
requirements: []
|
121
|
-
|
122
|
-
rubygems_version: 2.7.3
|
117
|
+
rubygems_version: 3.0.3
|
123
118
|
signing_key:
|
124
119
|
specification_version: 4
|
125
120
|
summary: A ssh_config manager for AWS EC2
|
@@ -127,11 +122,9 @@ test_files:
|
|
127
122
|
- spec/aws_sdk_compatibility_spec.rb
|
128
123
|
- spec/lib/ec2ssh/builder_spec.rb
|
129
124
|
- spec/lib/ec2ssh/command/init_spec.rb
|
130
|
-
- spec/lib/ec2ssh/command/migrate_spec.rb
|
131
125
|
- spec/lib/ec2ssh/command/remove_spec.rb
|
132
126
|
- spec/lib/ec2ssh/command/update_spec.rb
|
133
127
|
- spec/lib/ec2ssh/dsl_spec.rb
|
134
128
|
- spec/lib/ec2ssh/ec2_instances_spec.rb
|
135
|
-
- spec/lib/ec2ssh/migrator_spec.rb
|
136
129
|
- spec/lib/ec2ssh/ssh_config_spec.rb
|
137
130
|
- spec/spec_helper.rb
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'ec2ssh/exceptions'
|
2
|
-
require 'ec2ssh/command'
|
3
|
-
require 'ec2ssh/migrator'
|
4
|
-
|
5
|
-
module Ec2ssh
|
6
|
-
module Command
|
7
|
-
class Migrate < Base
|
8
|
-
def initialize(cli)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def run
|
13
|
-
migrator = Migrator.new dotfile_path
|
14
|
-
version = migrator.check_version
|
15
|
-
case version
|
16
|
-
when '2'
|
17
|
-
cli.red "Current dotfile version is #{version} (#{dotfile_path})"
|
18
|
-
new_dotfile_str = migrator.migrate_from_2
|
19
|
-
cli.red "Ec2ssh is migrating your dotfile to version 3 style as follows:"
|
20
|
-
cli.yellow new_dotfile_str
|
21
|
-
if cli.yes? "Are you sure to migrate #{dotfile_path} to version 3 style? (y/n)"
|
22
|
-
backup_path = migrator.backup!
|
23
|
-
puts "Creating backup as #{backup_path}"
|
24
|
-
migrator.replace! new_dotfile_str
|
25
|
-
cli.green 'Migrated successfully.'
|
26
|
-
end
|
27
|
-
when '3'
|
28
|
-
cli.green "Current dotfile version is #{version} (#{dotfile_path})"
|
29
|
-
cli.green 'Your dotfile is up-to-date.'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/lib/ec2ssh/migrator.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'stringio'
|
3
|
-
require 'ec2ssh/dsl'
|
4
|
-
|
5
|
-
module Ec2ssh
|
6
|
-
class Migrator
|
7
|
-
def initialize(dotfile_path)
|
8
|
-
@dotfile_path = dotfile_path
|
9
|
-
end
|
10
|
-
|
11
|
-
def dotfile_str
|
12
|
-
@dotfile_str ||= File.read(@dotfile_path)
|
13
|
-
end
|
14
|
-
|
15
|
-
def check_version
|
16
|
-
begin
|
17
|
-
hash = YAML.load dotfile_str
|
18
|
-
return '2' if hash.is_a?(Hash) && hash.keys.include?('aws_keys')
|
19
|
-
rescue Psych::SyntaxError
|
20
|
-
end
|
21
|
-
|
22
|
-
begin
|
23
|
-
Dsl::Parser.parse dotfile_str
|
24
|
-
return '3'
|
25
|
-
rescue DotfileSyntaxError
|
26
|
-
end
|
27
|
-
|
28
|
-
raise InvalidDotfile
|
29
|
-
end
|
30
|
-
|
31
|
-
def migrate_from_2
|
32
|
-
hash = YAML.load dotfile_str
|
33
|
-
out = StringIO.new
|
34
|
-
|
35
|
-
out.puts "path '#{hash['path']}'" if hash['path']
|
36
|
-
|
37
|
-
out.puts 'aws_keys('
|
38
|
-
out.puts hash['aws_keys'].map {|name, key|
|
39
|
-
" #{name}: { access_key_id: '#{key['access_key_id']}', secret_access_key: '#{key['secret_access_key']}' }"
|
40
|
-
}.join(",\n")
|
41
|
-
out.puts ')'
|
42
|
-
|
43
|
-
if hash['regions']
|
44
|
-
regions = hash['regions'].map{|r| "'#{r}'" }.join(', ')
|
45
|
-
out.puts "regions #{regions}"
|
46
|
-
end
|
47
|
-
|
48
|
-
out.puts <<-END
|
49
|
-
|
50
|
-
# Ignore unnamed instances
|
51
|
-
reject {|instance| !instance.tags['Name'] }
|
52
|
-
|
53
|
-
# You can use methods of AWS::EC2::Instance.
|
54
|
-
# See http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Instance.html
|
55
|
-
host_line <<EOS
|
56
|
-
Host <%= tags['Name'] %>.<%= availability_zone %>
|
57
|
-
HostName <%= dns_name || private_ip_address %>
|
58
|
-
EOS
|
59
|
-
END
|
60
|
-
|
61
|
-
out.puts
|
62
|
-
out.puts dotfile_str.gsub(/^/m, '# ')
|
63
|
-
|
64
|
-
out.string
|
65
|
-
end
|
66
|
-
|
67
|
-
def replace!(new_dotfile_str)
|
68
|
-
File.open(@dotfile_path, 'w') {|f| f.write new_dotfile_str }
|
69
|
-
end
|
70
|
-
|
71
|
-
def backup!
|
72
|
-
backup_path = "#{@dotfile_path}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
|
73
|
-
File.open(backup_path, 'w') {|f| f.write dotfile_str }
|
74
|
-
backup_path
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ec2ssh/command/migrate'
|
3
|
-
|
4
|
-
describe Ec2ssh::Command::Migrate do
|
5
|
-
include FakeFS::SpecHelpers
|
6
|
-
|
7
|
-
describe '#run' do
|
8
|
-
let(:cli) do
|
9
|
-
double(:cli,
|
10
|
-
options: options, yes?: nil,
|
11
|
-
red: nil, yellow: nil, green: nil)
|
12
|
-
end
|
13
|
-
let(:command) do
|
14
|
-
described_class.new cli
|
15
|
-
end
|
16
|
-
let(:options) do
|
17
|
-
double(:options, dotfile: '/dotfile')
|
18
|
-
end
|
19
|
-
|
20
|
-
before do
|
21
|
-
File.open('/dotfile', 'w') {|f| f.write dotfile_str }
|
22
|
-
end
|
23
|
-
|
24
|
-
around do |example|
|
25
|
-
silence_stdout { example.run }
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'version 2' do
|
29
|
-
let(:dotfile_str) { <<-END }
|
30
|
-
---
|
31
|
-
path: /path/to/ssh/config
|
32
|
-
aws_keys:
|
33
|
-
key1:
|
34
|
-
access_key_id: ACCESS_KEY1
|
35
|
-
secret_access_key: SECRET1
|
36
|
-
END
|
37
|
-
|
38
|
-
context 'yes' do
|
39
|
-
before do
|
40
|
-
expect(cli).to receive(:yes?).and_return(true)
|
41
|
-
Timecop.freeze(Time.utc(2014, 1, 1)) do
|
42
|
-
command.run
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
it do
|
47
|
-
expect(File.read('/dotfile')).to eq <<-END
|
48
|
-
path '/path/to/ssh/config'
|
49
|
-
aws_keys(
|
50
|
-
key1: { access_key_id: 'ACCESS_KEY1', secret_access_key: 'SECRET1' }
|
51
|
-
)
|
52
|
-
|
53
|
-
# Ignore unnamed instances
|
54
|
-
reject {|instance| !instance.tags['Name'] }
|
55
|
-
|
56
|
-
# You can use methods of AWS::EC2::Instance.
|
57
|
-
# See http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Instance.html
|
58
|
-
host_line <<EOS
|
59
|
-
Host <%= tags['Name'] %>.<%= availability_zone %>
|
60
|
-
HostName <%= dns_name || private_ip_address %>
|
61
|
-
EOS
|
62
|
-
|
63
|
-
# ---
|
64
|
-
# path: /path/to/ssh/config
|
65
|
-
# aws_keys:
|
66
|
-
# key1:
|
67
|
-
# access_key_id: ACCESS_KEY1
|
68
|
-
# secret_access_key: SECRET1
|
69
|
-
END
|
70
|
-
end
|
71
|
-
|
72
|
-
it do
|
73
|
-
expect(File.read('/dotfile.20140101000000')).to eq(dotfile_str)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'no' do
|
78
|
-
before do
|
79
|
-
expect(cli).to receive(:yes?).and_return(false)
|
80
|
-
command.run
|
81
|
-
end
|
82
|
-
|
83
|
-
it do
|
84
|
-
expect(File.read('/dotfile')).to eq(dotfile_str)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'version 3' do
|
90
|
-
let(:dotfile_str) { <<-END }
|
91
|
-
path '/path/to/ssh/config'
|
92
|
-
aws_keys(
|
93
|
-
key1: { access_key_id: 'ACCESS_KEY1', secret_access_key: 'SECRET1' }
|
94
|
-
)
|
95
|
-
|
96
|
-
# You can use methods of AWS::EC2::Instance.
|
97
|
-
# See http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Instance.html
|
98
|
-
host_line <<EOS
|
99
|
-
Host <%= tags['Name'] %>.<%= availability_zone %>
|
100
|
-
HostName <%= dns_name || private_ip_address %>
|
101
|
-
EOS
|
102
|
-
END
|
103
|
-
|
104
|
-
before do
|
105
|
-
command.run
|
106
|
-
end
|
107
|
-
|
108
|
-
it do
|
109
|
-
expect(File.read('/dotfile')).to eq(dotfile_str)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ec2ssh/migrator'
|
3
|
-
|
4
|
-
describe Ec2ssh::Migrator do
|
5
|
-
include FakeFS::SpecHelpers
|
6
|
-
|
7
|
-
subject(:migrator) { described_class.new '/dotfile' }
|
8
|
-
|
9
|
-
before do
|
10
|
-
File.open('/dotfile', 'w') {|f| f.write dotfile_str }
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'from version 2' do
|
14
|
-
let(:dotfile_str) { <<-END }
|
15
|
-
---
|
16
|
-
path: /path/to/ssh/config
|
17
|
-
aws_keys:
|
18
|
-
key1:
|
19
|
-
access_key_id: ACCESS_KEY1
|
20
|
-
secret_access_key: SECRET1
|
21
|
-
key2:
|
22
|
-
access_key_id: ACCESS_KEY2
|
23
|
-
secret_access_key: SECRET2
|
24
|
-
regions:
|
25
|
-
- ap-northeast-1
|
26
|
-
- us-east-1
|
27
|
-
END
|
28
|
-
|
29
|
-
let(:new_dotfile_str) { <<-END }
|
30
|
-
path '/path/to/ssh/config'
|
31
|
-
aws_keys(
|
32
|
-
key1: { access_key_id: 'ACCESS_KEY1', secret_access_key: 'SECRET1' },
|
33
|
-
key2: { access_key_id: 'ACCESS_KEY2', secret_access_key: 'SECRET2' }
|
34
|
-
)
|
35
|
-
regions 'ap-northeast-1', 'us-east-1'
|
36
|
-
|
37
|
-
# Ignore unnamed instances
|
38
|
-
reject {|instance| !instance.tags['Name'] }
|
39
|
-
|
40
|
-
# You can use methods of AWS::EC2::Instance.
|
41
|
-
# See http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Instance.html
|
42
|
-
host_line <<EOS
|
43
|
-
Host <%= tags['Name'] %>.<%= availability_zone %>
|
44
|
-
HostName <%= dns_name || private_ip_address %>
|
45
|
-
EOS
|
46
|
-
|
47
|
-
# ---
|
48
|
-
# path: /path/to/ssh/config
|
49
|
-
# aws_keys:
|
50
|
-
# key1:
|
51
|
-
# access_key_id: ACCESS_KEY1
|
52
|
-
# secret_access_key: SECRET1
|
53
|
-
# key2:
|
54
|
-
# access_key_id: ACCESS_KEY2
|
55
|
-
# secret_access_key: SECRET2
|
56
|
-
# regions:
|
57
|
-
# - ap-northeast-1
|
58
|
-
# - us-east-1
|
59
|
-
END
|
60
|
-
|
61
|
-
it { expect(migrator.check_version).to eq('2') }
|
62
|
-
it { expect(migrator.migrate_from_2).to eq(new_dotfile_str) }
|
63
|
-
end
|
64
|
-
end
|