puppet-pssh 0.1

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.
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: []