puppet-pssh 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.md +17 -0
  3. data/Rakefile +35 -0
  4. data/bin/puppet-pssh +3 -0
  5. data/lib/puppet-pssh.rb +152 -0
  6. metadata +165 -0
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Sergio Rubio <rubiojr@frameos.org>
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.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # puppet-pssh
2
+
3
+ Puppet parallel-ssh integration
4
+
5
+ # Install
6
+
7
+ gem install puppet-pssh
8
+
9
+ # Usage
10
+
11
+ puppet-pssh --help
12
+
13
+ # Copyright
14
+
15
+ Copyright (c) 2012 Sergio Rubio. See LICENSE.txt for
16
+ further details.
17
+
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require './lib/puppet-pssh.rb'
4
+
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
8
+ gem.version = PuppetPSSH::VERSION
9
+ gem.name = "puppet-pssh"
10
+ gem.homepage = "http://github.com/rubiojr/puppet-pssh"
11
+ gem.license = "MIT"
12
+ gem.summary = %Q{Puppet parallel-ssh integration}
13
+ gem.description = %Q{Puppet parallel-ssh integration}
14
+ gem.email = "rubiojr@frameos.org"
15
+ gem.authors = ["Sergio Rubio"]
16
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
17
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
18
+ gem.add_runtime_dependency 'colored'
19
+ gem.add_runtime_dependency 'excon'
20
+ gem.add_runtime_dependency 'net-dns'
21
+ gem.add_runtime_dependency 'json'
22
+ gem.add_runtime_dependency 'clamp'
23
+ gem.add_development_dependency 'rspec', '> 1.2.3'
24
+ gem.add_development_dependency 'jeweler'
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :build
data/bin/puppet-pssh ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), '/../lib/puppet-pssh.rb')
3
+ PuppetPSSH::Driver.run
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ require 'clamp'
3
+ require 'excon'
4
+ require 'json'
5
+ require 'logger'
6
+ require 'colored'
7
+
8
+ module PuppetPSSH
9
+
10
+ VERSION = "0.1"
11
+
12
+ if !defined? Log or Log.nil?
13
+ Log = Logger.new($stdout)
14
+ Log.formatter = proc do |severity, datetime, progname, msg|
15
+ if severity == "INFO"
16
+ "*".bold.cyan + " #{msg}\n"
17
+ else
18
+ severity = severity.red.bold if severity == 'ERROR'
19
+ severity = severity.yellow.bold if severity == 'WARN'
20
+ "#{Time.now.to_i} #{severity}: #{msg}\n"
21
+ end
22
+ end
23
+ Log.level = Logger::INFO unless (ENV["DEBUG"].eql? "yes" or ENV["DEBUG"].eql? 'true')
24
+ Log.debug "Initializing logger"
25
+ end
26
+
27
+
28
+ class BaseCommand < Clamp::Command
29
+
30
+ option ["-m", "--match"], "REGEX", "Only the nodes matching the regex", :default => '.*'
31
+ option ["-p", "--puppetmaster"], "PUPPETMASTER", "Puppet master host", :default => 'puppet'
32
+ option "--puppetmaster-port", "PUPPETMASTER_PORT", "Puppet master port", :default => '8080'
33
+ option "--use-ssl", :flag, "Use SSL (https) to communicate with the puppetmaster", :default => false
34
+ option "--debug", :flag, "Print debugging output", :default => false do |o|
35
+ Log.level = Logger::DEBUG
36
+ end
37
+
38
+ def get_nodes(puppetmaster)
39
+ url = "#{use_ssl? ? 'https' : 'http'}://#{puppetmaster}:#{puppetmaster_port}/nodes"
40
+ Log.debug "Puppet master host: #{puppetmaster}"
41
+ Log.debug "Puppet master url: #{url}"
42
+
43
+ nodes = []
44
+ begin
45
+ out = Excon.get url
46
+ JSON.parse(out.body).each do |n|
47
+ next unless n =~ /#{match}/
48
+ nodes << n
49
+ end
50
+ rescue TypeError => e
51
+ raise Exception.new "Error retrieving node list from master host: #{puppetmaster}"
52
+ rescue Excon::Errors::SocketError => e
53
+ raise Exception.new "Could not connect to the puppet master host: #{puppetmaster}"
54
+ end
55
+ nodes
56
+ end
57
+
58
+ end
59
+
60
+ class List < BaseCommand
61
+
62
+ def execute
63
+ begin
64
+ get_nodes(puppetmaster).each { |n| puts n }
65
+ rescue Exception => e
66
+ Log.error e.message
67
+ exit 1
68
+ end
69
+ end
70
+ end
71
+
72
+ #
73
+ # Run an arbitrary command using parallel-ssh against all the nodes
74
+ # registered in the puppet master
75
+ #
76
+ # Needs pssh (parallel-ssh) installed.
77
+ #
78
+ class Run < BaseCommand
79
+
80
+ parameter "COMMAND ...", "Command to run"
81
+ option "--nameserver", "DNS_SERVER", "Resolve node name using the given nameserver"
82
+ option "--pssh-path", "PSSH_PATH", "Parallel-ssh command path", :default => '/usr/bin/parallel-ssh'
83
+ option "--hostlist-path", "HOSTLIST_PATH", "Save host list to path", :default => '/tmp/puppet-pssh-run-hostlist'
84
+ option ["-H", "--hostlist-path"], "HOSTLIST_PATH", "Save host list to path", :default => '/tmp/puppet-pssh-run-hostlist'
85
+ option ["-o", "--node-output-path"], "NODE_OUTPUT_PATH", "Save host list to path", :default => '/tmp/'
86
+ option "--[no-]host-key-verify", :flag, "Verify SSH host key", :default => true
87
+
88
+ def execute
89
+ unless File.exist?(pssh_path)
90
+ Log.error "parallel-ssh command not found in #{pssh_path}."
91
+ Log.error "Install it or use --pssh-path argument."
92
+ exit 1
93
+ end
94
+
95
+ nodes = []
96
+ begin
97
+ nodes = get_nodes(puppetmaster)
98
+ rescue => e
99
+ Log.error e.message
100
+ exit 1
101
+ end
102
+
103
+ unless File.exist?(hostlist_path)
104
+ Log.info "Generating hostlist..."
105
+ Log.debug "Hostlist path: #{hostlist_path}"
106
+ #
107
+ # Optionally resolve names using specific DNS server
108
+ #
109
+ unless nameserver.nil?
110
+ require 'net/dns'
111
+ Log.info "DNS Server: #{nameserver}"
112
+ Log.info "Resolving node names... (may take a while)"
113
+ res = Net::DNS::Resolver.new
114
+ res.nameservers = nameserver
115
+ end
116
+ #
117
+ File.open hostlist_path, 'w' do |f|
118
+ nodes.each do |i|
119
+ address = i
120
+ # try to resolve before writing the list
121
+ Log.debug "Adding #{address}"
122
+ unless nameserver.nil?
123
+ address = res.query(i).answer.first.address rescue next
124
+ end
125
+ f.puts "#{address} root"
126
+ end
127
+ end
128
+ else
129
+ Log.warn "Using cached hostlist in #{hostlist_path}"
130
+ end
131
+
132
+ $stdout.sync = true
133
+ command = "sleep `echo $[ ( $RANDOM % 30 ) + 1 ]`;" + command_list.join(' ')
134
+ Log.info "Node log output path: #{node_output_path}"
135
+ Log.info "Running command '#{command}' with parallel-ssh..."
136
+ ssh_opts = ''
137
+ unless host_key_verify?
138
+ Log.warn 'Disabled host key verification'
139
+ ssh_opts = '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
140
+ end
141
+ system "#{pssh_path} -p 40 -o #{node_output_path} -t 300 -h #{hostlist_path} -x '#{ssh_opts}' " + "'#{command} 2>&1'"
142
+ end
143
+ end
144
+
145
+ class Driver < Clamp::Command
146
+
147
+ subcommand "run", "Run an arbitrary command against the nodes", Run
148
+ subcommand "list", "List registered nodes", List
149
+
150
+ end
151
+
152
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-pssh
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sergio Rubio
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: colored
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: excon
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: net-dns
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: clamp
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>'
100
+ - !ruby/object:Gem::Version
101
+ version: 1.2.3
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>'
108
+ - !ruby/object:Gem::Version
109
+ version: 1.2.3
110
+ - !ruby/object:Gem::Dependency
111
+ name: jeweler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Puppet parallel-ssh integration
127
+ email: rubiojr@frameos.org
128
+ executables:
129
+ - puppet-pssh
130
+ extensions: []
131
+ extra_rdoc_files:
132
+ - LICENSE.txt
133
+ - README.md
134
+ files:
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - bin/puppet-pssh
139
+ - lib/puppet-pssh.rb
140
+ homepage: http://github.com/rubiojr/puppet-pssh
141
+ licenses:
142
+ - MIT
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 1.8.24
162
+ signing_key:
163
+ specification_version: 3
164
+ summary: Puppet parallel-ssh integration
165
+ test_files: []