remoter 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andrey Subbotin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = remoter
2
+
3
+ A tool to simplify executing of shell command on several remote machines over SSH.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Andrey Subbotin. See LICENSE for details.
@@ -0,0 +1,28 @@
1
+ module Remoter
2
+
3
+ autoload :Base, 'remoter/base'
4
+ autoload :Session, 'remoter/session'
5
+ autoload :UI, 'remoter/ui'
6
+
7
+ class RemoterError < StandardError
8
+ def self.status_code(code = nil)
9
+ define_method(:status_code) { code }
10
+ end
11
+ end
12
+
13
+ class SCPError < RemoterError; status_code(10); end
14
+ class EXEError < RemoterError; status_code(11); end
15
+
16
+ class << self
17
+ attr_writer :ui
18
+
19
+ def ui
20
+ @ui ||= UI.new
21
+ end
22
+
23
+ def read_file(file)
24
+ File.open(file, "rb") { |f| f.read }
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thor'
4
+ require 'nmap/parser'
5
+
6
+ module Remoter
7
+ class Base < Thor
8
+
9
+ def initialize(*)
10
+ super
11
+ the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
12
+ Remoter.ui = UI::Shell.new(the_shell)
13
+ Remoter.ui.debug! if options["verbose"]
14
+ end
15
+
16
+ class_option "no-color", :type => :boolean, :desc => "Disable colorization in output"
17
+ class_option "verbose", :type => :boolean, :desc => "Enable verbose output mode", :aliases => "-v"
18
+ class_option "workers", :type => :numeric, :desc => "Number of parallel SSH sessions", :aliases => "-w", :default => 5
19
+ class_option "username", :type => :string, :desc => "Username to use for the SSH sessions", :aliases => "-u"
20
+
21
+ protected
22
+
23
+ def self.beam(name, &block)
24
+ self.send :method_option, "targets", :type => :array, :alias => "-t", :required => true, :desc =>
25
+ "Can pass hostnames, IP addresses, networks, etc. Ex: some.agent.org, ouragents.com/24, 192.168.0.1; 10.0.0-255.1-254"
26
+ self.send :method_option, "exclude", :type => :array, :desc =>
27
+ "Exclude hosts/networks."
28
+ define_method name do
29
+ workers = []
30
+ items_per_worker = (hosts.count.to_f / options['workers'].to_f).ceil
31
+ hosts.each_slice(items_per_worker).to_a.each_with_index do |targets, worker_no|
32
+ Remoter.ui.debug "WORKER ##{worker_no}: #{targets.count}"
33
+ workers << Process.fork do
34
+ Remoter.ui.debug "WORKER ##{worker_no}: Proceeding with #{targets.count} agents..."
35
+ while (target = targets.shift)
36
+ Remoter.ui.debug "WORKER ##{worker_no}: PROCESSING #{target.addr}..."
37
+ begin
38
+ send Base.body_method_name(name), Session.new(self, target)
39
+ rescue RemoterError => error
40
+ Remoter.ui.error "WORKER ##{worker_no}: ERROR: #{error.message}"
41
+ Remoter.ui.error "WORKER ##{worker_no}: FAILED for #{target.addr}... WILL RETRY"
42
+ targets.push target
43
+ else
44
+ Remoter.ui.confirm "WORKER ##{worker_no}: SUCEEDED for #{target.addr}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ workers.each { |pid| Process.wait(pid) }
50
+ Remoter.ui.confirm "ALL DONE. KEWL."
51
+ end
52
+ no_tasks do
53
+ define_method body_method_name(name), block
54
+ end
55
+ end
56
+
57
+ def parser
58
+ @parser ||= Nmap::Parser.parsescan('nmap', nmap_args)
59
+ end
60
+
61
+ def nmap_args
62
+ result = "-sP"
63
+ result += " --exclude #{options['exclude'].join(',')}" if options['exclude']
64
+ result += " #{options['targets'].join(' ')}"
65
+ result
66
+ end
67
+
68
+ def hosts
69
+ @hosts ||= parser.hosts('up')
70
+ end
71
+
72
+ private
73
+
74
+ def self.body_method_name(beam_name) ; "#{beam_name.to_s}_body".to_sym ; end
75
+
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ require 'shellwords'
2
+
3
+ module Remoter
4
+ class Session
5
+ attr_reader :remoter
6
+ attr_reader :target
7
+
8
+ def initialize(_remoter, _target)
9
+ @remoter = _remoter
10
+ @target = _target
11
+ end
12
+
13
+ def scp(from, to)
14
+ target_cmd = "scp -o StrictHostKeyChecking=no \"#{from}\" \"#{user_part}#{target.addr}:#{to.shellescape}\""
15
+ raise SCPError, "The following command failed: #{target_cmd}" unless system(target_cmd)
16
+ end
17
+
18
+ def exe(cmd)
19
+ target_cmd = "ssh #{user_part}#{target.addr} -o StrictHostKeyChecking=no \"#{cmd}\""
20
+ raise EXEError, "The following command failed: #{target_cmd}" unless system(target_cmd)
21
+ end
22
+
23
+ private
24
+
25
+ def user_part
26
+ remoter.options['username'] ? "#{remoter.options['username']}@" : ''
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,56 @@
1
+ module Remoter
2
+ class UI
3
+ def warn(message)
4
+ end
5
+
6
+ def debug(message)
7
+ end
8
+
9
+ def error(message)
10
+ end
11
+
12
+ def info(message)
13
+ end
14
+
15
+ def confirm(message)
16
+ end
17
+
18
+ class Shell < UI
19
+ attr_writer :shell
20
+
21
+ def initialize(shell)
22
+ @shell = shell
23
+ @quiet = false
24
+ @debug = ENV['DEBUG']
25
+ end
26
+
27
+ def debug(msg)
28
+ @shell.say(msg) if @debug && !@quiet
29
+ end
30
+
31
+ def info(msg)
32
+ @shell.say(msg) if !@quiet
33
+ end
34
+
35
+ def confirm(msg)
36
+ @shell.say(msg, :green) if !@quiet
37
+ end
38
+
39
+ def warn(msg)
40
+ @shell.say(msg, :yellow)
41
+ end
42
+
43
+ def error(msg)
44
+ @shell.say(msg, :red)
45
+ end
46
+
47
+ def be_quiet!
48
+ @quiet = true
49
+ end
50
+
51
+ def debug!
52
+ @debug = true
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ module Remoter
2
+ module Version
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+ BUILD = 'pre1'
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remoter
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ - pre1
10
+ version: 1.0.0.pre1
11
+ platform: ruby
12
+ authors:
13
+ - Andrey Subbotin
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-14 00:00:00 -08:00
19
+ default_executable: []
20
+
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: nmap-parser
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ prerelease: false
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: thor
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *id002
48
+ description: A tool to simplify executing of shell command on several remote machines over SSH.
49
+ email: andrey@subbotin.me
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files:
55
+ - LICENSE
56
+ - README.rdoc
57
+ files:
58
+ - LICENSE
59
+ - README.rdoc
60
+ - lib/remoter.rb
61
+ - lib/remoter/base.rb
62
+ - lib/remoter/session.rb
63
+ - lib/remoter/ui.rb
64
+ - lib/remoter/version.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/eploko/remoter
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">"
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 1
89
+ - 3
90
+ - 1
91
+ version: 1.3.1
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Run commands on multiple remote machines over SSH easily.
99
+ test_files: []
100
+