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 +4 -4
- data/bin/lanes +1 -1
- data/changelog.md +4 -0
- data/lib/lanes.rb +148 -120
- data/lib/lanes/file.rb +47 -0
- data/lib/lanes/version.rb +1 -1
- data/notes.md +3 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d072ed56adc4c6f6211370b5e46e499b0a6588f
|
4
|
+
data.tar.gz: ec38a657af92f32bb0fd18cffce2467ade3ef437
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faa63eeea13925c549668162254e4e8f730dc459fd2b7d2f77686a996315b61030d0c9214bbb3f93583a5833563ed62e152a413bcbc0b52cae952733d3725006
|
7
|
+
data.tar.gz: 83103bf61c7306333fd64e1ef1bf55b1f60cf8c9fe327bca02db0bba0b3d309df627c5e5e6020cc33454552767f43ac13c3772a20b377de91355ae924c68768b
|
data/bin/lanes
CHANGED
data/changelog.md
ADDED
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
|
-
|
10
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
puts "
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
124
|
+
sleep 5 if servers.length > 0
|
125
|
+
puts "\t => #{servers.length} server(s) remaining..." if servers.length > 0
|
126
|
+
end
|
106
127
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
158
|
+
choice = ask "Which server: "
|
159
|
+
chosen = servers[ choice.to_i - 1 ] if choice != ''
|
160
|
+
end
|
161
|
+
}
|
162
|
+
end
|
144
163
|
|
145
|
-
|
146
|
-
|
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
|
-
|
149
|
-
|
172
|
+
# hijack the AwsCli file variable
|
173
|
+
ENV['AWSCLI_CONFIG_FILE']="~/.lanes/#{profile}.yml"
|
150
174
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
data/notes.md
CHANGED
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.
|
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:
|
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
|