aws-ssh 1.0.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/aws-ssh +18 -13
  3. data/bin/awssh +1 -0
  4. metadata +3 -4
  5. data/bin/awssh +0 -162
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6982e9f815c9f9271c5176348bf1ec46afea3a74
4
- data.tar.gz: 79cffa033b806b19c8f1a406d897027ec9dfba5b
3
+ metadata.gz: 4b0810c9f39a7a08a1da018725f544033769ba09
4
+ data.tar.gz: e7cb343982032d66e38dab1024b17b0cbf1e63f3
5
5
  SHA512:
6
- metadata.gz: 45f2bf73998b7d28e1545d6a9d3a39adfc4bd248acc4aca59075acbedfaaccf42a858ce12e9f46d84429e1e2a0ee6c1bdd9286ad92bb1e1e4cb830574cce7cc6
7
- data.tar.gz: aa594d1686abe4202fb97f2fb7e41048b589f41f91018380ae36634dd807d2195cd92a117143870b7bdc760cd2d0b22514ec8a3854e0b88f8b0985e7c4804e15
6
+ metadata.gz: 80ab44660e1e6b860d4bb5961ff421b12599e01291b31a414165071d29c1605ef75a8a68b7bdc5ec5a68897f346003957c2e5649c094519cccaeda31eb32bba2
7
+ data.tar.gz: b97b74819572525b07eb07edb52c0d4692cff0b0fa376d14852728e45f6084229b8cdcd3f5dbfe6b4d5a53fc5a596ca7a369a5e42121fe616a1ad0259ae359aa
@@ -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!(profile: cli[:profile], region: cli[:region])
27
+ Aws.config.merge!(cli.to_h.select { |key| AWS_CONFIG_KEYS.include?(key) })
27
28
 
28
- if cli['show-only']
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.size > 1
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.\n"
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)} \t => #{i.name}"
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 = File.exist?('.awssh') ? YAML.load_file('.awssh') : {}
94
- DEFAULT_OPTIONS.merge(defaults)
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
- next unless word_match?(instance.name, host_regex, case_sensitive)
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
@@ -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.2
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: 2015-08-18 00:00:00.000000000 Z
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.4.3
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