aws-ssh 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/aws-ssh +162 -0
  3. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 528f3fee7a959f32e7e5cda371d4e35fe98fe403
4
- data.tar.gz: d5d3faf114cd04448bd45ea259d4b1a9e69b8428
3
+ metadata.gz: 78ca737b88d4a338e7f18dfab077b2fe7948d1ba
4
+ data.tar.gz: 3b14eb94c34a986a0afe5412e5167681ad599b93
5
5
  SHA512:
6
- metadata.gz: 037d03e913644404aad34e487c3709d1a62c1b068efe018583c653066dfa7f96f3a1b1b390e6f9ceff0a2651bede193185fa95e5a9b5d2dc9f2c6e346e5c901b
7
- data.tar.gz: 3560dd269f9687cd9f17a56cdd47b04d34031531887b948b527b537d4f419ab3d4d6a4f8c98aa9a8e53d04646b4b0c927356b530801f5700b6a0b10ba63a2c40
6
+ metadata.gz: 7643046e0babf3bd28ee73ebc595148929dd14524aa02992c4b1e91c05f385d31b65521c43470181af647cb0082689eb8aada2567fe21f580a364064dcfbd78b
7
+ data.tar.gz: fe55c550ecda8d8dfdd1577a06b1ca7a97becce04299218d6d332f95bf1708d4f251b02a2b5c686d4e6a1da3c0913ad01236672e885a58c824d9da719922d83a
@@ -0,0 +1,162 @@
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
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.0
4
+ version: 1.0.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: 2015-08-17 00:00:00.000000000 Z
11
+ date: 2015-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slop
@@ -43,11 +43,13 @@ email:
43
43
  - rafaelcds@gmail.com
44
44
  executables:
45
45
  - awssh
46
+ - aws-ssh
46
47
  extensions: []
47
48
  extra_rdoc_files: []
48
49
  files:
50
+ - bin/aws-ssh
49
51
  - bin/awssh
50
- homepage: https://github.com/buzzstarter/awssh
52
+ homepage: https://github.com/buzzstarter/aws-ssh
51
53
  licenses:
52
54
  - MIT
53
55
  metadata: {}