aws-ssh 1.0.2 → 1.1.1
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/bin/aws-ssh +18 -13
- data/bin/awssh +1 -0
- metadata +3 -4
- data/bin/awssh +0 -162
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b0810c9f39a7a08a1da018725f544033769ba09
|
4
|
+
data.tar.gz: e7cb343982032d66e38dab1024b17b0cbf1e63f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80ab44660e1e6b860d4bb5961ff421b12599e01291b31a414165071d29c1605ef75a8a68b7bdc5ec5a68897f346003957c2e5649c094519cccaeda31eb32bba2
|
7
|
+
data.tar.gz: b97b74819572525b07eb07edb52c0d4692cff0b0fa376d14852728e45f6084229b8cdcd3f5dbfe6b4d5a53fc5a596ca7a369a5e42121fe616a1ad0259ae359aa
|
data/bin/aws-ssh
CHANGED
@@ -11,6 +11,7 @@ module AWSSH
|
|
11
11
|
'format' => 'ssh',
|
12
12
|
'verbose' => false
|
13
13
|
}
|
14
|
+
AWS_CONFIG_KEYS = [:profile, :region]
|
14
15
|
|
15
16
|
attr_accessor :host_regex
|
16
17
|
|
@@ -23,13 +24,9 @@ module AWSSH
|
|
23
24
|
shout "Options: #{cli.to_h.inspect}"
|
24
25
|
shout "Defaults: #{defaults.inspect}"
|
25
26
|
|
26
|
-
Aws.config.merge!(
|
27
|
+
Aws.config.merge!(cli.to_h.select { |key| AWS_CONFIG_KEYS.include?(key) })
|
27
28
|
|
28
|
-
|
29
|
-
print_output
|
30
|
-
else
|
31
|
-
ssh!
|
32
|
-
end
|
29
|
+
cli['show-only'] ? print_output : ssh!
|
33
30
|
end
|
34
31
|
|
35
32
|
def cli
|
@@ -51,6 +48,10 @@ Examples:
|
|
51
48
|
|
52
49
|
# All hosts in one-line (suitable for CSSH):
|
53
50
|
worker@10.20.30.40 worker@10.20.30.41
|
51
|
+
|
52
|
+
The config file .awssh is looked up in following directories:
|
53
|
+
./ (current directory)
|
54
|
+
~/ ($HOME directory)
|
54
55
|
USAGE
|
55
56
|
|
56
57
|
o.separator "Options:"
|
@@ -69,16 +70,18 @@ Examples:
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def ssh!
|
72
|
-
if instances.
|
73
|
+
if instances.empty?
|
74
|
+
exit_error! "No hostname matched."
|
75
|
+
elsif instances.size > 1
|
73
76
|
print_output
|
74
|
-
exit_error! "\nMultiple hostnames matched. Please be more specific in hostnames regex or use the last output line to use CSSH
|
77
|
+
exit_error! "\nMultiple hostnames matched. Please be more specific in hostnames regex or use the last output line to use CSSH."
|
75
78
|
end
|
76
79
|
exec "ssh #{connection_string(instances.first)}"
|
77
80
|
end
|
78
81
|
|
79
82
|
def print_output
|
80
83
|
instances.each do |i|
|
81
|
-
puts "ssh #{connection_string(i)}
|
84
|
+
puts "ssh #{connection_string(i).ljust(30, ' ')} => #{i.name}"
|
82
85
|
end
|
83
86
|
puts "\n# All hosts in one-line (suitable for CSSH):"
|
84
87
|
puts instances.map { |i| connection_string(i) }.join(' ')
|
@@ -90,8 +93,9 @@ Examples:
|
|
90
93
|
|
91
94
|
def defaults
|
92
95
|
@defaults ||= begin
|
93
|
-
defaults =
|
94
|
-
|
96
|
+
defaults = YAML.load_file('.awssh') if File.exist?('.awssh')
|
97
|
+
defaults ||= YAML.load_file("#{ENV['HOME']}/.awssh") if File.exist?("#{ENV['HOME']}/.awssh")
|
98
|
+
DEFAULT_OPTIONS.merge(defaults) if defaults
|
95
99
|
end
|
96
100
|
end
|
97
101
|
|
@@ -105,6 +109,7 @@ Examples:
|
|
105
109
|
|
106
110
|
def exit_error!(msg)
|
107
111
|
$stderr.puts msg
|
112
|
+
$stderr.puts
|
108
113
|
exit(1)
|
109
114
|
end
|
110
115
|
|
@@ -140,8 +145,8 @@ Examples:
|
|
140
145
|
next unless word_match?(instance.stack_name, stack_regex, case_sensitive)
|
141
146
|
end
|
142
147
|
if host_regex
|
143
|
-
next unless word_match?(instance.hostname, host_regex, case_sensitive)
|
144
|
-
|
148
|
+
next unless word_match?(instance.hostname, host_regex, case_sensitive) ||
|
149
|
+
word_match?(instance.name, host_regex, case_sensitive)
|
145
150
|
end
|
146
151
|
|
147
152
|
instance
|
data/bin/awssh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bin/aws-ssh
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Sales
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|
@@ -69,9 +69,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
version: '0'
|
70
70
|
requirements: []
|
71
71
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.
|
72
|
+
rubygems_version: 2.6.8
|
73
73
|
signing_key:
|
74
74
|
specification_version: 4
|
75
75
|
summary: A tool that makes easy to ssh into AWS EC2 servers
|
76
76
|
test_files: []
|
77
|
-
has_rdoc:
|
data/bin/awssh
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'slop'
|
4
|
-
require 'aws-sdk'
|
5
|
-
require 'yaml'
|
6
|
-
|
7
|
-
module AWSSH
|
8
|
-
class Runner
|
9
|
-
DEFAULT_OPTIONS = {
|
10
|
-
'user' => ENV['user'],
|
11
|
-
'format' => 'ssh',
|
12
|
-
'verbose' => false
|
13
|
-
}
|
14
|
-
|
15
|
-
attr_accessor :host_regex
|
16
|
-
|
17
|
-
def run
|
18
|
-
self.host_regex = cli.args.first
|
19
|
-
exit_error! 'AWS Region not set' unless cli[:region]
|
20
|
-
exit_error! 'AWS Profile not set' unless cli[:profile]
|
21
|
-
|
22
|
-
shout "Hostname: #{host_regex}"
|
23
|
-
shout "Options: #{cli.to_h.inspect}"
|
24
|
-
shout "Defaults: #{defaults.inspect}"
|
25
|
-
|
26
|
-
Aws.config.merge!(profile: cli[:profile], region: cli[:region])
|
27
|
-
|
28
|
-
if cli['show-only']
|
29
|
-
print_output
|
30
|
-
else
|
31
|
-
ssh!
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def cli
|
36
|
-
@cli ||= Slop.parse do |o|
|
37
|
-
o.banner = <<-USAGE
|
38
|
-
awssh - a tool that makes easy to ssh into AWS EC2 servers
|
39
|
-
|
40
|
-
Usage: awssh [hostname regex]
|
41
|
-
|
42
|
-
Examples:
|
43
|
-
$ awssh prod.*app2
|
44
|
-
... will SSH into the instance and you will see:
|
45
|
-
user@prod-rails-app4~$
|
46
|
-
|
47
|
-
$ awssh --show-only --stack qa -u worker
|
48
|
-
... will show all instances registered in QA stack of Opsworks
|
49
|
-
ssh worker@10.20.30.40 => MyApp QA - qa-rails-app
|
50
|
-
ssh worker@10.20.30.41 => MyApp QA - qa-sidekiq
|
51
|
-
|
52
|
-
# All hosts in one-line (suitable for CSSH):
|
53
|
-
worker@10.20.30.40 worker@10.20.30.41
|
54
|
-
USAGE
|
55
|
-
|
56
|
-
o.separator "Options:"
|
57
|
-
o.string '-s', '--stack', 'AWS OpsWorks Stack name regex. E.g: `-s prod` will match "Production" stack name'
|
58
|
-
o.string '-p', '--profile', 'AWS config profile name. Default: profile set in .awssh file', default: defaults['profile']
|
59
|
-
o.string '-r', '--region', 'AWS region. E.g: us-east-1. Default: region set in .awssh file', default: defaults['region']
|
60
|
-
o.string '-u', '--user', 'SSH username to use. Default: user set in .awssh file or current machine user', default: defaults['user']
|
61
|
-
o.bool '-so', '--show-only', 'Only show the matched hosts instead of ssh. Default: false', default: false
|
62
|
-
o.bool '-cs', '--csensitive', 'Use case-sensitive for regex matching. Default: false', default: false
|
63
|
-
o.bool '-v', '--verbose', 'Verbose mode. Default: false', default: false
|
64
|
-
o.on '--help', 'Shows help' do
|
65
|
-
puts o
|
66
|
-
exit
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def ssh!
|
72
|
-
if instances.size > 1
|
73
|
-
print_output
|
74
|
-
exit_error! "\nMultiple hostnames matched. Please be more specific in hostnames regex or use the last output line to use CSSH.\n"
|
75
|
-
end
|
76
|
-
exec "ssh #{connection_string(instances.first)}"
|
77
|
-
end
|
78
|
-
|
79
|
-
def print_output
|
80
|
-
instances.each do |i|
|
81
|
-
puts "ssh #{connection_string(i)} \t => #{i.name}"
|
82
|
-
end
|
83
|
-
puts "\n# All hosts in one-line (suitable for CSSH):"
|
84
|
-
puts instances.map { |i| connection_string(i) }.join(' ')
|
85
|
-
end
|
86
|
-
|
87
|
-
def connection_string(instance)
|
88
|
-
"#{cli[:user]}@#{instance.ip}"
|
89
|
-
end
|
90
|
-
|
91
|
-
def defaults
|
92
|
-
@defaults ||= begin
|
93
|
-
defaults = File.exist?('.awssh') ? YAML.load_file('.awssh') : {}
|
94
|
-
DEFAULT_OPTIONS.merge(defaults)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def instances
|
99
|
-
@instances ||= AWSEC2.new.instances(host_regex, cli[:stack], cli[:csensitive]).select do |i|
|
100
|
-
shout "Instance #{i.name} is not part of an Opsworks Stack" unless i.stack_name
|
101
|
-
shout "Instance #{i.name} not running. Current state: #{i.state}" unless i.running?
|
102
|
-
i.running?
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def exit_error!(msg)
|
107
|
-
$stderr.puts msg
|
108
|
-
exit(1)
|
109
|
-
end
|
110
|
-
|
111
|
-
def shout(msg)
|
112
|
-
puts "[DEBUG] #{msg}" if cli.verbose?
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
EC2Instance = Struct.new(:name, :hostname, :stack_name, :state, :ip) do
|
117
|
-
def initialize(instance)
|
118
|
-
name = extract_tag(instance, 'Name')
|
119
|
-
hostname = extract_tag(instance, 'opsworks:instance')
|
120
|
-
stack_name = extract_tag(instance, 'opsworks:stack')
|
121
|
-
|
122
|
-
super(name, hostname, stack_name, instance.state.name, instance.public_ip_address)
|
123
|
-
end
|
124
|
-
|
125
|
-
def running?
|
126
|
-
state == 'running'
|
127
|
-
end
|
128
|
-
|
129
|
-
def extract_tag(instance, tag)
|
130
|
-
tag = instance.tags.find { |t| t.key == tag }
|
131
|
-
tag ? tag.value : nil
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
class AWSEC2
|
136
|
-
def instances(host_regex, stack_regex, case_sensitive)
|
137
|
-
ec2.describe_instances.reservations.map(&:instances).flatten.map do |instance_data|
|
138
|
-
instance = EC2Instance.new(instance_data)
|
139
|
-
if stack_regex
|
140
|
-
next unless word_match?(instance.stack_name, stack_regex, case_sensitive)
|
141
|
-
end
|
142
|
-
if host_regex
|
143
|
-
next unless word_match?(instance.hostname, host_regex, case_sensitive)
|
144
|
-
next unless word_match?(instance.name, host_regex, case_sensitive)
|
145
|
-
end
|
146
|
-
|
147
|
-
instance
|
148
|
-
end.compact.sort_by(&:name)
|
149
|
-
end
|
150
|
-
|
151
|
-
def ec2
|
152
|
-
@ec2 ||= Aws::EC2::Client.new
|
153
|
-
end
|
154
|
-
|
155
|
-
def word_match?(value, regex_str, case_sensitive)
|
156
|
-
regex = case_sensitive ? /#{regex_str}/ : /#{regex_str}/i
|
157
|
-
!!(value =~ regex)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
AWSSH::Runner.new.run
|