aws-ssh 1.0.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/aws-ssh +34 -25
- data/bin/awssh +1 -0
- metadata +22 -10
- data/bin/awssh +0 -162
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 95f7d7c849326eabeacf2f9e3010424fdae6d1791983070726fd371926e9a284
|
4
|
+
data.tar.gz: 87e154a952299dc9f7eb7cb46bb69114ed5e684643f1ad4e33cdf45e9fe3d015
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0bc9261566eb918f77afab42fdf859b9a61261de226c913ab161dcf78f89213d83b01dc971770146280c2dc1f5354ffb4f00f032139f2b32234a9cedd4065bf
|
7
|
+
data.tar.gz: 03220f46695d3ee3c98781d046906532c0acc5e29f1b843dab914f9d392d78156975d0cc18eed34c07098cf5d22089ba71dd37b988f1244253f0bb92fa1bbe11
|
data/bin/aws-ssh
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'slop'
|
4
|
-
require 'aws-sdk'
|
4
|
+
require 'aws-sdk-ec2'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
|
-
module
|
7
|
+
module AWSSSH
|
8
8
|
class Runner
|
9
9
|
DEFAULT_OPTIONS = {
|
10
10
|
'user' => ENV['user'],
|
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,43 +24,43 @@ 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
|
36
33
|
@cli ||= Slop.parse do |o|
|
37
34
|
o.banner = <<-USAGE
|
38
|
-
|
35
|
+
aws-ssh - a tool that makes easy to ssh into AWS EC2 servers
|
39
36
|
|
40
|
-
Usage:
|
37
|
+
Usage: aws-ssh [hostname regex]
|
41
38
|
|
42
39
|
Examples:
|
43
|
-
$
|
40
|
+
$ aws-ssh prod.*app2
|
44
41
|
... will SSH into the instance and you will see:
|
45
42
|
user@prod-rails-app4~$
|
46
43
|
|
47
|
-
$
|
44
|
+
$ aws-ssh --show-only --stack qa -u worker
|
48
45
|
... will show all instances registered in QA stack of Opsworks
|
49
46
|
ssh worker@10.20.30.40 => MyApp QA - qa-rails-app
|
50
47
|
ssh worker@10.20.30.41 => MyApp QA - qa-sidekiq
|
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 .aws-ssh is looked up in following directories:
|
53
|
+
./ (current directory)
|
54
|
+
~/ ($HOME directory)
|
54
55
|
USAGE
|
55
56
|
|
56
57
|
o.separator "Options:"
|
57
|
-
o.string '-s', '--stack', '
|
58
|
-
o.string '-p', '--profile', 'AWS config profile name. Default: profile set in .
|
59
|
-
o.string '-r', '--region', 'region. E.g: us-east-1. Default: region set in .
|
60
|
-
o.string '-u', '--user', 'SSH username to use. Default: user set in .
|
58
|
+
o.string '-s', '--stack', 'AWS OpsWorks Stack name regex. E.g: `-s prod` will match "Production" stack name'
|
59
|
+
o.string '-p', '--profile', 'AWS config profile name. Default: profile set in .aws-ssh file', default: defaults['profile']
|
60
|
+
o.string '-r', '--region', 'AWS region. E.g: us-east-1. Default: region set in .aws-ssh file', default: defaults['region']
|
61
|
+
o.string '-u', '--user', 'SSH username to use. Default: user set in .aws-ssh file or current machine user', default: defaults['user']
|
61
62
|
o.bool '-so', '--show-only', 'Only show the matched hosts instead of ssh. Default: false', default: false
|
62
|
-
o.bool '-cs', '--csensitive', '
|
63
|
+
o.bool '-cs', '--csensitive', 'Use case-sensitive for regex matching. Default: false', default: false
|
63
64
|
o.bool '-v', '--verbose', 'Verbose mode. Default: false', default: false
|
64
65
|
o.on '--help', 'Shows help' do
|
65
66
|
puts o
|
@@ -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,13 @@ Examples:
|
|
90
93
|
|
91
94
|
def defaults
|
92
95
|
@defaults ||= begin
|
93
|
-
|
94
|
-
|
96
|
+
if File.exist?('.awssh') || File.exist?("#{ENV['HOME']}/.awssh")
|
97
|
+
puts 'WARNING: please rename the config file .awssh to .aws-ssh'
|
98
|
+
exit(1)
|
99
|
+
end
|
100
|
+
defaults = YAML.load_file('.aws-ssh') if File.exist?('.aws-ssh')
|
101
|
+
defaults ||= YAML.load_file("#{ENV['HOME']}/.aws-ssh") if File.exist?("#{ENV['HOME']}/.aws-ssh")
|
102
|
+
DEFAULT_OPTIONS.merge(defaults) if defaults
|
95
103
|
end
|
96
104
|
end
|
97
105
|
|
@@ -105,6 +113,7 @@ Examples:
|
|
105
113
|
|
106
114
|
def exit_error!(msg)
|
107
115
|
$stderr.puts msg
|
116
|
+
$stderr.puts
|
108
117
|
exit(1)
|
109
118
|
end
|
110
119
|
|
@@ -140,8 +149,8 @@ Examples:
|
|
140
149
|
next unless word_match?(instance.stack_name, stack_regex, case_sensitive)
|
141
150
|
end
|
142
151
|
if host_regex
|
143
|
-
next unless word_match?(instance.hostname, host_regex, case_sensitive)
|
144
|
-
|
152
|
+
next unless word_match?(instance.hostname, host_regex, case_sensitive) ||
|
153
|
+
word_match?(instance.name, host_regex, case_sensitive)
|
145
154
|
end
|
146
155
|
|
147
156
|
instance
|
@@ -159,4 +168,4 @@ Examples:
|
|
159
168
|
end
|
160
169
|
end
|
161
170
|
|
162
|
-
|
171
|
+
AWSSSH::Runner.new.run
|
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.0
|
4
|
+
version: 1.3.0
|
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: 2022-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|
@@ -25,31 +25,45 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: aws-sdk
|
28
|
+
name: aws-sdk-ec2
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.11.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.11.0
|
41
55
|
description: A tool that makes easy to ssh into AWS EC2 servers
|
42
56
|
email:
|
43
57
|
- rafaelcds@gmail.com
|
44
58
|
executables:
|
45
|
-
- awssh
|
46
59
|
- aws-ssh
|
60
|
+
- awssh
|
47
61
|
extensions: []
|
48
62
|
extra_rdoc_files: []
|
49
63
|
files:
|
50
64
|
- bin/aws-ssh
|
51
65
|
- bin/awssh
|
52
|
-
homepage: https://github.com/
|
66
|
+
homepage: https://github.com/rafaelsales/aws-ssh
|
53
67
|
licenses:
|
54
68
|
- MIT
|
55
69
|
metadata: {}
|
@@ -68,10 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
82
|
- !ruby/object:Gem::Version
|
69
83
|
version: '0'
|
70
84
|
requirements: []
|
71
|
-
|
72
|
-
rubygems_version: 2.4.3
|
85
|
+
rubygems_version: 3.0.3.1
|
73
86
|
signing_key:
|
74
87
|
specification_version: 4
|
75
88
|
summary: A tool that makes easy to ssh into AWS EC2 servers
|
76
89
|
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', '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', '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', 'Uses 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
|