awslanes 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37d90d5f27a2891f0a42b2d35da7865a187a5861
4
- data.tar.gz: 95aaf39d579f4bfb653241f7c62cd92c80724435
3
+ metadata.gz: 4d072ed56adc4c6f6211370b5e46e499b0a6588f
4
+ data.tar.gz: ec38a657af92f32bb0fd18cffce2467ade3ef437
5
5
  SHA512:
6
- metadata.gz: 48df3eb16491ede1992270ff40fa12a8557402d2cb2b60828817fba11dbd140d8e2b874c64ec358a0bf5b1a9e5582a7ccff3354f133bd4084d2c34e6f52f607d
7
- data.tar.gz: 97c6ef8db23064ee54dec28009da504c98d92152af955e855641a583ddcf411fcd42b87b7cd20fae647ad03735c706054c4a90914ede24367b2907782192e88a
6
+ metadata.gz: faa63eeea13925c549668162254e4e8f730dc459fd2b7d2f77686a996315b61030d0c9214bbb3f93583a5833563ed62e152a413bcbc0b52cae952733d3725006
7
+ data.tar.gz: 83103bf61c7306333fd64e1ef1bf55b1f60cf8c9fe327bca02db0bba0b3d309df627c5e5e6020cc33454552767f43ac13c3772a20b377de91355ae924c68768b
data/bin/lanes CHANGED
@@ -13,6 +13,6 @@ ENV['AWSCLI_CONFIG_FILE']="~/.lanes/#{profile}.yml"
13
13
  settings = YAML.load_file( ENV['HOME'] + "/.lanes/#{profile}.yml")
14
14
 
15
15
  Props.instance.set(settings)
16
- Lanes.start(ARGV)
17
16
 
17
+ LanesCli::Lanes.start( ARGV )
18
18
  # TODO close the connection in the singleton
data/changelog.md ADDED
@@ -0,0 +1,4 @@
1
+ # 0.0.4
2
+ - Added ability to "switch" profiles
3
+ - Configurable delay on 'sh' via `--urlConfirmDelay` property
4
+ - Added initial file support, with ability to push files (see `lanes file push`)
data/lib/lanes.rb CHANGED
@@ -1,155 +1,183 @@
1
+
1
2
  require "lanes/version"
2
3
  require "lanes/aws"
3
4
  require "lanes/props"
5
+ require "lanes/file"
4
6
  require "thor"
5
7
  require 'yaml'
6
8
  require 'awscli'
7
9
  require 'rest_client'
8
10
 
9
- class Lanes < Thor
10
- desc "list [LANE]", "Lists all servers name + ip + Instance ID, optionally filtered by lane 2"
11
- def list(lane=nil)
12
- servers = AWS.instance.fetchServers(lane)
13
- servers.sort_by{ |s| s[:lane] }
14
- servers.each{|server|
15
- puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
16
- }
17
- end
11
+ module LanesCli
12
+ class Lanes < Thor
18
13
 
19
- desc "ssh [LANE]", "Lists all servers name + ip + Instance ID, optionally filtered by lane, and prompts which one for ssh"
20
- def ssh(lane=nil)
21
- chosen = chooseServer(lane)
22
- if chosen != nil
23
- mods = Props.instance.sshMod(chosen[:lane])
24
- identity = if mods['identity'] then '-i ' + mods['identity'] else '' end
25
- tunnel = if mods['tunnel'] then '-L' + mods['tunnel'] else '' end
26
-
27
- cmd = "ssh ec2-user@%{ip} #{identity} #{tunnel}" % chosen
28
- exec cmd
29
- else
30
- puts 'Canceled'
14
+ desc "switch [profile]", "Switches AWS profiles (e.g. ~/.lanes/lanes.yml entry)"
15
+ def switch(profile)
16
+ path = ENV['HOME'] + '/.lanes/lanes.yml'
17
+ data = YAML.load_file path
18
+ data["profile"] = profile
19
+ File.open(path, 'w') { |f| YAML.dump(data, f) }
20
+ puts "Switched to #{profile}"
31
21
  end
32
- end
33
22
 
34
- method_option :cmd, :type => :array
35
- method_option :urlConfirm, :type => :string
36
- method_option :urlConfirmTimeout, :type => :numeric
37
- method_option :v, :type => :boolean
38
- method_option :confirm, :type => :boolean
39
- desc "sh [LANE] ", "Executes a command on all machines with support for confirming an endpoint is available after"
40
- def sh(lane)
41
- servers = AWS.instance.fetchServers(lane)
42
- servers.sort_by{ |s| s[:ip] }
43
-
44
- puts "Available Servers: "
45
- servers.each_with_index {|server|
46
- puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
47
- }
48
23
 
49
24
 
50
- mods = Props.instance.sshMod(lane)
51
- identity = if mods['identity'] then mods['identity'] else '' end
52
- puts "Identity file #{mods['identity']} will be used" if identity
53
25
 
54
- command = options[:cmd].join(' ')
55
- if options[:confirm] then
56
- puts "Confirmed via command line. Moving forward with execution of \"#{command}\" on these machines:"
57
- confirm = 'CONFIRM'
58
- else
59
- confirm = ask "Type CONFIRM to execute \"#{command} \" on these machines:"
26
+ desc "list [LANE]", "Lists all servers name + ip + Instance ID, optionally filtered by lane 2"
27
+ def list(lane=nil)
28
+ servers = AWS.instance.fetchServers(lane)
29
+ servers.sort_by{ |s| s[:lane] }
30
+ servers.each{|server|
31
+ puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
32
+ }
60
33
  end
61
34
 
62
- if confirm == 'CONFIRM' then
63
- servers.each{ |server|
64
- Net::SSH.start( server[:ip], 'ec2-user',
65
- :keys => [identity],
66
- # :verbose => :debug,
67
- :encryption => "blowfish-cbc",
68
- :compression => "zlib",
69
- :host_key => "ssh-rsa") do |ssh|
70
- puts "Executing on %{name} ( %{ip} ):\t #{command} \n" % server
71
- stdout = ''
72
- ssh.exec!(command) do |channel, stream, data|
73
- stdout << data
74
- end
75
- puts "Completed. %{name}\n\tOutput: #{stdout}\n\n " % server
76
- end
35
+ desc "ssh [LANE]", "Lists all servers name + ip + Instance ID, optionally filtered by lane, and prompts which one for ssh"
36
+ def ssh(lane=nil)
37
+ chosen = chooseServer(lane)
38
+ if chosen != nil
39
+ mods = Props.instance.sshMod(chosen[:lane])
40
+ identity = if mods['identity'] then '-i ' + mods['identity'] else '' end
41
+ tunnel = if mods['tunnel'] then '-L' + mods['tunnel'] else '' end
42
+ user = if mods['user'] then mods['user'] else 'ec2-user' end
43
+ cmd = "ssh #{user}@%{ip} #{identity} #{tunnel}" % chosen
44
+ exec cmd
45
+ else
46
+ puts 'Canceled'
47
+ end
48
+ end
49
+
50
+
51
+ method_option :cmd, :type => :array
52
+ method_option :urlConfirm, :type => :string
53
+ method_option :urlConfirmTimeout, :type => :numeric
54
+ method_option :urlConfirmDelay, :type => :numeric
55
+ method_option :v, :type => :boolean
56
+ method_option :confirm, :type => :boolean
57
+ desc "sh [LANE] ", "Executes a command on all machines with support for confirming an endpoint is available after"
58
+ def sh(lane)
59
+ servers = AWS.instance.fetchServers(lane)
60
+ servers.sort_by{ |s| s[:ip] }
61
+
62
+ puts "Available Servers: "
63
+ servers.each_with_index {|server|
64
+ puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
77
65
  }
78
66
 
79
67
 
80
- confirmPath = options[:urlConfirm]
81
- if confirmPath != nil then
82
- confirmTimeout = (options[:urlConfirmTimeout] or 30);
83
- startTime = Time.new.to_i
84
-
85
- # we better sleep for a few, otherwise the shutdown won't have executed
86
- puts "Sleeping for 5 seconds, then trying the confirmation endpoint for #{confirmTimeout} seconds..."
87
- sleep 5
88
- while Time.new.to_i - startTime < confirmTimeout && servers.length > 0 do
89
- servers.each_with_index{ |server, index|
90
- begin
91
- res = RestClient.get (confirmPath % server)
92
- if res.code >= 200 && res.code < 300 then
93
- puts "\t => #{server[:ip]} responded with #{res.code}"
94
- servers.delete_at(index)
95
- else
96
- puts "\t XX #{server[:ip]} responded with #{res.code}" if options[:v]
68
+ mods = Props.instance.sshMod(lane)
69
+ identity = if mods['identity'] then mods['identity'] else '' end
70
+ puts "Identity file #{mods['identity']} will be used" if identity
71
+
72
+ command = options[:cmd].join(' ')
73
+ if options[:confirm] then
74
+ puts "Confirmed via command line. Moving forward with execution of \"#{command}\" on these machines:"
75
+ confirm = 'CONFIRM'
76
+ else
77
+ confirm = ask "Type CONFIRM to execute \"#{command} \" on these machines:"
78
+ end
79
+
80
+ if confirm == 'CONFIRM' then
81
+ servers.each{ |server|
82
+ user = if mods['user'] then mods['user'] else 'ec2-user' end
83
+ Net::SSH.start( server[:ip], user,
84
+ :keys => [identity],
85
+ # :verbose => :debug,
86
+ :encryption => "blowfish-cbc",
87
+ :compression => "zlib",
88
+ :host_key => "ssh-rsa") do |ssh|
89
+ puts "Executing on %{name} ( %{ip} ):\t #{command} \n" % server
90
+ stdout = ''
91
+ ssh.exec!(command) do |channel, stream, data|
92
+ stdout << data
97
93
  end
98
- rescue => e
99
- puts "\t XX #{server[:ip]} connection failed: #{e}" if options[:v]
94
+ puts "Completed. %{name}\n\tOutput: #{stdout}\n\n " % server
100
95
  end
101
- }
96
+ }
97
+
98
+
99
+
100
+ confirmPath = options[:urlConfirm]
101
+ if confirmPath != nil then
102
+ confirmDelay = (options[:urlConfirmDelay] or 5)
103
+ confirmTimeout = (options[:urlConfirmTimeout] or 30);
104
+ startTime = Time.new.to_i
105
+
106
+ # we better sleep for a few, otherwise the shutdown won't have executed
107
+ puts "Sleeping for #{confirmDelay} seconds, then trying the confirmation endpoint for #{confirmTimeout} seconds..."
108
+ sleep confirmDelay
109
+ while Time.new.to_i - startTime < confirmTimeout && servers.length > 0 do
110
+ servers.each_with_index{ |server, index|
111
+ begin
112
+ res = RestClient.get (confirmPath % server)
113
+ if res.code >= 200 && res.code < 300 then
114
+ puts "\t => #{server[:ip]} responded with #{res.code}"
115
+ servers.delete_at(index)
116
+ else
117
+ puts "\t XX #{server[:ip]} responded with #{res.code}" if options[:v]
118
+ end
119
+ rescue => e
120
+ puts "\t XX #{server[:ip]} connection failed: #{e}" if options[:v]
121
+ end
122
+ }
102
123
 
103
- sleep 5 if servers.length > 0
104
- puts "\t => #{servers.length} server(s) remaining..." if servers.length > 0
105
- end
124
+ sleep 5 if servers.length > 0
125
+ puts "\t => #{servers.length} server(s) remaining..." if servers.length > 0
126
+ end
106
127
 
107
- if servers.length == 0 then
108
- puts "Successfully confirmed endpoints responded with a 2XX"
109
- else
110
- puts "The following server(s) did not respond with a 2XX:"
111
- servers.each{ |server|
112
- puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
113
- }
128
+ if servers.length == 0 then
129
+ puts "Successfully confirmed endpoints responded with a 2XX"
130
+ else
131
+ puts "The following server(s) did not respond with a 2XX:"
132
+ servers.each{ |server|
133
+ puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
134
+ }
135
+ end
114
136
  end
137
+ else
138
+ puts 'Aborted!'
139
+ exit 1
115
140
  end
116
- else
117
- puts 'Aborted!'
118
- exit 1
119
141
  end
120
- end
121
142
 
143
+ desc 'file SUBCOMMAND ...ARGS', 'Push / pull files'
144
+ subcommand 'file', LanesCli::FileCmd
122
145
 
123
- no_commands{
124
- def chooseServer(lane=nul)
125
- servers = AWS.instance.fetchServers(lane)
126
- servers.sort_by{ |s| s[:lane] }
127
146
 
128
- puts "Available Servers: "
129
- servers.each_with_index {|server, index|
130
- i = index + 1
131
- puts "\t#{i}) %{name} (%{lane}) \t %{ip} \t %{id} " % server
132
- }
147
+ no_commands{
148
+ def chooseServer(lane=nul)
149
+ servers = AWS.instance.fetchServers(lane)
150
+ servers.sort_by{ |s| s[:lane] }
133
151
 
134
- choice = ask "Which server: "
135
- chosen = servers[ choice.to_i - 1 ] if choice != ''
136
- end
137
- }
138
- end
152
+ puts "Available Servers: "
153
+ servers.each_with_index {|server, index|
154
+ i = index + 1
155
+ puts "\t#{i}) %{name} (%{lane}) \t %{ip} \t %{id} " % server
156
+ }
139
157
 
140
- if ENV['RUBYMINE'] != nil
141
- # load the Lanes settings file
142
- config = YAML.load_file( ENV['HOME'] + '/.lanes/lanes.yml')
143
- profile = config['profile']
158
+ choice = ask "Which server: "
159
+ chosen = servers[ choice.to_i - 1 ] if choice != ''
160
+ end
161
+ }
162
+ end
144
163
 
145
- # hijack the AwsCli file variable
146
- ENV['AWSCLI_CONFIG_FILE']="~/.lanes/#{profile}.yml"
164
+ ################################################################
165
+ # IMPORTANT: IF YOU CHANGE STUFF BELOW, CHANGE IT IN bin/lanes #
166
+ ################################################################
167
+ if ENV['RUBYMINE'] != nil
168
+ # load the Lanes settings file
169
+ config = YAML.load_file( ENV['HOME'] + '/.lanes/lanes.yml')
170
+ profile = config['profile']
147
171
 
148
- # Populate our properties singleton as well
149
- settings = YAML.load_file( ENV['HOME'] + "/.lanes/#{profile}.yml")
172
+ # hijack the AwsCli file variable
173
+ ENV['AWSCLI_CONFIG_FILE']="~/.lanes/#{profile}.yml"
150
174
 
151
- Props.instance.set(settings)
152
- Lanes.start( ENV['RUBYMINE'].split(' ') )
153
- # TODO close the connection in the singleton
154
- end
175
+ # Populate our properties singleton as well
176
+ settings = YAML.load_file( ENV['HOME'] + "/.lanes/#{profile}.yml")
177
+
178
+ Props.instance.set(settings)
155
179
 
180
+ LanesCli::Lanes.start( ENV['RUBYMINE'].split(' ') )
181
+ # TODO close the connection in the singleton
182
+ end
183
+ end
data/lib/lanes/file.rb ADDED
@@ -0,0 +1,47 @@
1
+ require "thor"
2
+ module LanesCli
3
+ class FileCmd < Thor
4
+
5
+ method_option :confirm, :type => :boolean
6
+ desc "push [target] [destination] [LANE]", "Pushes [file] to [destination] on all [LANE] instances "
7
+ def push(target, dest, lane=nil)
8
+ pwd = Dir.pwd
9
+ puts "#{pwd} #{target} #{dest} #{lane}"
10
+ file = "#{pwd}/#{target}"
11
+
12
+ servers = AWS.instance.fetchServers(lane)
13
+ servers.sort_by{ |s| s[:lane] }
14
+ puts 'Servers that will receive the file:'
15
+ servers.each{|server|
16
+ puts "\t%{name} (%{lane}) \t %{ip} \t %{id} " % server
17
+ }
18
+
19
+
20
+ mods = Props.instance.sshMod(lane)
21
+ identity = if mods['identity'] then mods['identity'] else '' end
22
+ puts "Identity file #{mods['identity']} will be used" if identity
23
+
24
+ if options[:confirm] then
25
+ puts 'Confirmed via command line. Moving forward with execution..'
26
+ confirm = 'CONFIRM'
27
+ else
28
+ confirm = ask 'Type CONFIRM to begin pushing files:'
29
+ end
30
+
31
+
32
+ if confirm == 'CONFIRM' then
33
+ servers.each{|server|
34
+ id = if identity then "-i #{identity}" else '' end
35
+ user = if mods['user'] then mods['user'] else 'ec2-user' end
36
+ cmd = "scp #{id} #{file} #{user}@%{ip}:#{dest}" % server
37
+ puts " => Executing: #{cmd}"
38
+ result = system cmd
39
+ if !result then
40
+ puts 'WARNING: Failed on %{ip}' % server
41
+ end
42
+ }
43
+ end
44
+
45
+ end
46
+ end
47
+ end
data/lib/lanes/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module AwsLanes
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/notes.md CHANGED
@@ -1,2 +1,4 @@
1
1
  To test it locally:
2
- ```gem build awslanes.gemspec && gem install awslanes-*.gem```
2
+ ```
3
+ gem build awslanes.gemspec && gem install awslanes-*.gem
4
+ ```
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awslanes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Welch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-05 00:00:00.000000000 Z
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -95,8 +95,10 @@ files:
95
95
  - Rakefile
96
96
  - awslanes.gemspec
97
97
  - bin/lanes
98
+ - changelog.md
98
99
  - lib/lanes.rb
99
100
  - lib/lanes/aws.rb
101
+ - lib/lanes/file.rb
100
102
  - lib/lanes/props.rb
101
103
  - lib/lanes/version.rb
102
104
  - notes.md