ec2ssh 3.1.1 → 4.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 +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
|