runpuppet 1.0.0.rc1 → 1.0.0.rc2

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.
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source "http://rubygems.org"
5
5
 
6
6
  gem 'rest-client'
7
7
  gem 'facter'
8
+ gem 'dim'
8
9
  # Add dependencies to develop your gem here.
9
10
  # Include everything needed to run rake, tests, features, etc.
10
11
  group :development do
data/Gemfile.lock CHANGED
@@ -1,6 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ dim (1.2.2)
4
5
  facter (1.6.14)
5
6
  git (1.2.5)
6
7
  jeweler (1.8.4)
@@ -25,6 +26,7 @@ PLATFORMS
25
26
 
26
27
  DEPENDENCIES
27
28
  bundler (~> 1.2.0)
29
+ dim
28
30
  facter
29
31
  jeweler
30
32
  minitest (= 4.1.0)
data/README.rdoc CHANGED
@@ -11,6 +11,28 @@ cat /etc/runpuppet.yml:
11
11
  lock_file: /tmp/runpuppet.lock
12
12
 
13
13
 
14
+ ### Run tests
15
+
16
+ sh/test
17
+
18
+
19
+ #### Start console
20
+
21
+ sh/c
22
+
23
+ #### Playing in console
24
+
25
+ @ctx = Runpuppet.setup_context({})
26
+
27
+ # client
28
+ @ctx.client
29
+
30
+ # config
31
+ @ctx.config
32
+
33
+ # agent ### HTTP agent
34
+ @ctx.agent
35
+
14
36
 
15
37
 
16
38
  This is the companion for our puppet_controller, a light-weight web-service to coordinate local puppet runs on servers.
@@ -27,6 +49,6 @@ This is the companion for our puppet_controller, a light-weight web-service to c
27
49
 
28
50
  == Copyright
29
51
 
30
- Copyright (c) 2011 Roman Heinrich. See LICENSE.txt for
52
+ Copyright (c) 2012 Roman Heinrich. See LICENSE.txt for
31
53
  further details.
32
54
 
data/Rakefile CHANGED
@@ -32,7 +32,7 @@ Rake::TestTask.new do |t|
32
32
  end
33
33
 
34
34
 
35
- require 'rake/rdoctask'
35
+ require 'rdoc/task'
36
36
  Rake::RDocTask.new do |rdoc|
37
37
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
38
38
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.20
1
+ 1.0.0.rc2
data/bin/runpuppet CHANGED
@@ -20,17 +20,19 @@ BANNER
20
20
 
21
21
  opts.on("-h", "--help","Show this.") { puts opts; exit }
22
22
  opts.on("--readme", 'Show Readme'){ puts File.read(File.join(File.dirname(__FILE__), '..', 'README.rdoc')); exit }
23
- opts.on('-v', '--version','Show Version'){ puts Runpuppet::VERSION; exit}
24
- opts.on('--try','Runs only if selected on puppet_controller'){ options[:try] = true }
25
- opts.on('-f', '--facts','Report facts'){ options[:facts] = true }
26
- opts.on('--verbose','Verbose Output'){ options[:verbose] = true }
23
+ opts.on('--version', 'Show Version'){ puts Runpuppet::VERSION; exit}
24
+ opts.on('--try', 'Runs only if selected on puppet_controller'){ options[:try] = true }
25
+ opts.on('-f', '--facts', 'Report facts'){ options[:facts] = true }
26
+ opts.on('-v', '--verbose', 'Execute Verbose Command'){ options[:verbose] = true }
27
+ opts.on('-d', '--debug', 'With debug output'){ options[:debug] = true }
27
28
  opts.on('-b x', '--branch x', 'Run this branch') do |branch|
28
29
  options[:branch] = branch
29
30
  end
30
31
  end.parse!
31
32
 
33
+ PuppetContext = Runpuppet.setup_context(options)
32
34
  if options[:facts]
33
- Runpuppet.report_facts
35
+ PuppetContext.client.report_facts
34
36
  else
35
- Runpuppet.run(options)
36
- end
37
+ PuppetContext.client.run
38
+ end
data/lib/ext/core.rb ADDED
@@ -0,0 +1,8 @@
1
+ class Array
2
+ # [[1,2]] => {1=>2}
3
+ def to_hash
4
+ hash = {}
5
+ each {|k,v| hash[k]=v}
6
+ hash
7
+ end
8
+ end
data/lib/runpuppet.rb CHANGED
@@ -2,151 +2,41 @@ require 'open-uri'
2
2
  require 'socket'
3
3
  require 'yaml'
4
4
  require 'rest-client'
5
- require 'core-ext'
6
-
7
- STDOUT.sync = true
8
-
9
- class Runpuppet
10
- def self.with_lock(lock_file)
11
- recently_locked = (File.exists?(lock_file) and File.mtime(lock_file) > Time.now - 15*60)
12
-
13
- if recently_locked
14
- puts "can not run, lockfile #{lock_file} exists"
15
- else
16
- begin
17
- `touch #{lock_file}`
18
- yield
19
- ensure
20
- `rm #{lock_file}`
21
- end
22
- end
23
- end
24
-
25
- # simplified copy of rake`s sh
26
- def self.sh(cmd)
27
- puts cmd
28
- IO.popen(cmd) do |pipe|
29
- while str = pipe.gets
30
- puts str
31
- end
32
- end
33
- $?.success?
34
- end
35
-
36
-
37
- def self.get(path, options={})
38
- path += (path.include?('?') ? '&' : '?')
39
- path += "hostname=#{Socket.gethostname}&ip=#{Config.local_ip}"
40
- begin
41
- url = Config.puppet_controller_url + path
42
- puts "Getting #{url}" if options[:verbose]
43
- RestClient.get(url)
44
- rescue Exception => e
45
- puts e.inspect
46
- puts "WARNING: error connecting in GET (PuppetMaster)"
47
- end
48
- end
49
-
50
-
51
- def self.post(path, params)
52
- params[:hostname] = Socket.gethostname
53
- params[:ip] = Config.local_ip
54
- begin
55
- RestClient.post "#{Config.puppet_controller_url}/puppet/#{path}", params
56
- rescue Exception => e
57
- puts e.inspect
58
- puts "WARNING: error connecting in POST (PuppetMaster)"
59
- end
60
- end
5
+ require 'dim'
61
6
 
7
+ require 'ext/core'
8
+ require 'runpuppet/config'
9
+ require 'runpuppet/client'
10
+ require 'runpuppet/agent'
11
+ require 'runpuppet/logger'
62
12
 
63
- def self.run(options={})
64
- with_lock(Config.lock_file) do
65
- time = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
66
-
67
- todo, branch = get("/puppet/run", options).split('-') rescue []
68
- puts "got #{todo} with branch #{branch}" if options[:verbose]
69
- branch ||= (options[:branch] || Config.default_branch)
70
- if todo == 'run' or !options[:try] # try allows not running
71
- get '/puppet/status?status=started', options
72
- cmd = Config.command.gsub('@@branch@@', branch)
73
- puts "#{time}: run #{branch}"
74
-
75
- if sh(cmd)
76
- get '/puppet/status?status=finished', options
77
- else
78
- get '/puppet/status?status=error', options
79
- exit 2
80
- end
81
- else
82
- puts "#{time}: nothing to do"
83
- end
84
- end
85
- end
86
-
87
- def self.report_facts(options={})
88
- require 'facter/application'
89
- facts = Facter::Application.run([])
90
- post('facts', :facts => facts.to_hash)
91
- end
92
-
93
-
94
- class Config
95
- def self.config
96
- home = File.expand_path('~')
97
- ["#{home}/.runpuppet.yml", '/etc/runpuppet.yml'].each do |file|
98
- return YAML.load(File.read(file)) if File.exist?(file)
99
- end
100
- raise "No runpuppet.yml found in /etc or #{home}"
101
- end
102
-
103
- def self.puppet_controller_url
104
- config['puppet_controller_url'].sub(%r{/$},'')
105
- end
13
+ STDOUT.sync = true
106
14
 
107
- def self.puppet_controller_auth
108
- extract_auth_from_url!(config['puppet_controller_url'])
109
- end
110
15
 
111
- def self.extract_auth_from_url!(url)
112
- url.sub!(%r{//(.*?):(.*?)@}, '//')
113
- auth = [$1, $2].compact
114
- auth.empty? ? nil : auth
115
- end
16
+ module Runpuppet
17
+ def self.setup_context(options={})
18
+ ctx = Dim::Container.new
116
19
 
117
- def self.lock_file
118
- config['lock_file'] || '/tmp/runpuppet.lock'
20
+ ctx.register(:run_options) do
21
+ options
119
22
  end
120
23
 
121
- def self.command
122
- config['command'] || "cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && puppet -v --debug --logdest console --modulepath /etc/puppet/repo/modules /etc/puppet/repo/manifests/site.pp"
24
+ ctx.register(:config) do
25
+ Runpuppet::Config.find_system_config
123
26
  end
124
27
 
125
- def self.default_branch
126
- config['branch'] || 'master'
28
+ ctx.register(:client) do |context|
29
+ Runpuppet::Client.new(context)
127
30
  end
128
31
 
129
- def self.local_ip
130
- if is_ec2?
131
- require 'facter'
132
- require 'facter/ec2'
133
- ip = Facter.value("ec2_public_ipv4")
134
- elsif config['local_ip_interface']
135
- parse_local_ip_from_interface
136
- else
137
- config['local_ip'] or %x(ifconfig)[/192.168.\d+.\d+/] or %x(ifconfig)[/10.10.\d+.\d+/]
138
- end
32
+ ctx.register(:agent) do |context|
33
+ Runpuppet::Agent.new(context)
139
34
  end
140
35
 
141
-
142
- def self.parse_local_ip_from_interface
143
- # %x(ifconfig #{config['local_ip_interface']}).lines.grep(/inet addr/).first.match(/addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
144
- %x(ip addr list #{config['local_ip_interface']}).match(/inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
145
- return $1
36
+ ctx.register(:logger) do
37
+ Runpuppet::Logger
146
38
  end
147
39
 
148
- def self.is_ec2?
149
- %x(arp -n -i eth0) =~ /fe:ff:ff:ff:ff/
150
- end
40
+ return ctx
151
41
  end
152
42
  end
@@ -0,0 +1,77 @@
1
+ ### http client
2
+ module Runpuppet
3
+ class Agent
4
+ attr_accessor :config
5
+ attr_accessor :run_options
6
+ def initialize(context)
7
+ @config = context.config
8
+ @run_options = context.run_options
9
+ end
10
+
11
+ ##### puppet
12
+
13
+ def check_status
14
+ action, branch = get("/puppet/run", @run_options).split('-') rescue []
15
+ branch ||= (run_options[:branch] || config.default_branch)
16
+ return action, branch
17
+ end
18
+
19
+ def report_start
20
+ get '/puppet/status?status=started'
21
+ end
22
+
23
+ def report_success
24
+ get '/puppet/status?status=finished'
25
+ end
26
+
27
+ def report_failure
28
+ get '/puppet/status?status=error'
29
+ end
30
+
31
+ def report_facts
32
+ require 'facter/application'
33
+ facts = Facter::Application.run([])
34
+ post('/puppet/facts', :facts => facts.to_hash)
35
+ end
36
+
37
+ #### base
38
+
39
+ def get(path)
40
+ begin
41
+ url = append_params_to_url(base_url(path))
42
+ puts "Getting #{url}" if run_options[:verbose]
43
+ result = RestClient.get(url)
44
+ puts "got #{result}" if run_options[:verbose]
45
+ rescue Exception => e
46
+ puts e.inspect
47
+ puts "WARNING: error connecting in GET (PuppetMaster)"
48
+ end
49
+ end
50
+
51
+ def post(path, params)
52
+ begin
53
+ RestClient.post base_url(path), append_params_to_post(params)
54
+ rescue Exception => e
55
+ puts e.inspect
56
+ puts "WARNING: error connecting in POST (PuppetMaster)"
57
+ end
58
+ end
59
+
60
+ def append_params_to_post(params)
61
+ params = params.dup
62
+ params[:hostname] = config.hostname
63
+ params[:ip] = config.local_ip
64
+ return params
65
+ end
66
+
67
+ def append_params_to_url(url)
68
+ url += (url.include?('?') ? '&' : '?')
69
+ url += "hostname=#{config.hostname}&ip=#{config.local_ip}"
70
+ url
71
+ end
72
+
73
+ def base_url(path)
74
+ "#{config.puppet_controller_url.gsub(/\/$/, '')}/#{path.gsub(/^\//, '')}"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,76 @@
1
+ module Runpuppet
2
+ class Client
3
+ attr_accessor :config
4
+ attr_accessor :run_options
5
+ attr_accessor :agent
6
+ attr_accessor :logger
7
+ def initialize(context)
8
+ @config = context.config
9
+ @run_options = context.run_options
10
+ @agent = context.agent
11
+ end
12
+
13
+ def run
14
+ with_lock(config.lock_file) do
15
+ action, branch = agent.check_status
16
+ if should_run?(action)
17
+ agent.report_start
18
+ log "run #{branch}"
19
+
20
+ if sh(run_command(branch))
21
+ agent.report_success
22
+ else
23
+ agent.report_failure
24
+ exit 2
25
+ end
26
+ else
27
+ log "nothing to do"
28
+ end
29
+ end
30
+ end
31
+
32
+ def run_command(branch)
33
+ cmd = if run_options[:verbose]
34
+ config.verbose_command
35
+ else
36
+ config.command
37
+ end
38
+ cmd.gsub('@@branch@@', branch)
39
+ end
40
+
41
+ def should_run?(action)
42
+ ## always run if started without --try
43
+ (!run_options[:try] or action == 'run')
44
+ end
45
+
46
+ def with_lock(lock_file)
47
+ recently_locked = (File.exists?(lock_file) and File.mtime(lock_file) > Time.now - 15*60)
48
+
49
+ if recently_locked
50
+ log "can not run, lockfile #{lock_file} exists"
51
+ else
52
+ begin
53
+ `touch #{lock_file}`
54
+ yield
55
+ ensure
56
+ `rm #{lock_file}`
57
+ end
58
+ end
59
+ end
60
+
61
+ # simplified copy of rake`s sh
62
+ def sh(cmd)
63
+ puts cmd
64
+ IO.popen(cmd) do |pipe|
65
+ while str = pipe.gets
66
+ puts str
67
+ end
68
+ end
69
+ $?.success?
70
+ end
71
+
72
+ def log(msg)
73
+ logger.log(msg)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,94 @@
1
+ module Runpuppet
2
+ class Config
3
+ attr_accessor :config_path
4
+ attr_accessor :data
5
+ def initialize(config_path)
6
+ @config_path = config_path
7
+ load_data
8
+ end
9
+
10
+
11
+ def load_data
12
+ raise "No runpuppet.yml found in #{config_path}" unless File.exist?(config_path)
13
+ @data = YAML.load(File.read(config_path))
14
+ end
15
+
16
+ def self.find_system_config
17
+ home = File.expand_path('~')
18
+ pathes = ["#{home}/.runpuppet.yml", '/etc/runpuppet.yml']
19
+ pathes.each do |file|
20
+ return Runpuppet::Config.new(file) if File.exist?(file)
21
+ end
22
+ puts "No runpuppet.yml found in #{pathes.join(' or ')}"
23
+ exit
24
+ end
25
+
26
+ def puppet_controller_url
27
+ data['puppet_controller_url'].sub(%r{/$},'')
28
+ end
29
+
30
+ def puppet_controller_auth
31
+ extract_auth_from_url!(puppet_controller_url)
32
+ end
33
+
34
+ def extract_auth_from_url!(url)
35
+ url.sub!(%r{//(.*?):(.*?)@}, '//')
36
+ auth = [$1, $2].compact
37
+ auth.empty? ? nil : auth
38
+ end
39
+
40
+ def lock_file
41
+ data['lock_file'] || '/tmp/runpuppet.lock'
42
+ end
43
+
44
+ def command
45
+ # "cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && puppet -v --debug --logdest console --modulepath /etc/puppet/repo/modules /etc/puppet/repo/manifests/site.pp"
46
+ data['command']
47
+ end
48
+
49
+ def verbose_command
50
+ unless data['verbose_command']
51
+ puts "No verbose_command param in #{config_path} found! using normal command."
52
+ return self.command
53
+ end
54
+ data['verbose_command']
55
+ end
56
+
57
+ def default_branch
58
+ data['branch'] || 'master'
59
+ end
60
+
61
+ def local_ip
62
+ if is_ec2?
63
+ require 'facter'
64
+ require 'facter/ec2'
65
+ ip = Facter.value("ec2_public_ipv4")
66
+ elsif data['local_ip_interface']
67
+ parse_local_ip_from_interface
68
+ else
69
+ ifconfig = read_shell('ifconfig')
70
+ data['local_ip'] or
71
+ ifconfig[/192.168.\d+.\d+/] or
72
+ ifconfig[/10.10.\d+.\d+/]
73
+ end
74
+ end
75
+
76
+ def hostname
77
+ Socket.gethostname
78
+ end
79
+
80
+ def parse_local_ip_from_interface
81
+ cmd = "ip addr list #{data['local_ip_interface']}"
82
+ read_shell(cmd).match(/inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
83
+ return $1
84
+ end
85
+
86
+ def is_ec2?
87
+ read_shell('arp -n -i eth0') =~ /fe:ff:ff:ff:ff/
88
+ end
89
+
90
+ def read_shell(cmd)
91
+ %x(#{cmd})
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,6 @@
1
+ class Logger
2
+ def self.log(msg)
3
+ time = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
4
+ puts "#{time}: #{msg}"
5
+ end
6
+ end
data/runpuppet.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "runpuppet"
8
- s.version = "1.0.0.rc1"
8
+ s.version = "1.0.0.rc2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Roman Heinrich"]
@@ -26,8 +26,23 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "bin/runpuppet",
29
+ "lib/ext/core.rb",
29
30
  "lib/runpuppet.rb",
31
+ "lib/runpuppet/agent.rb",
32
+ "lib/runpuppet/client.rb",
33
+ "lib/runpuppet/config.rb",
34
+ "lib/runpuppet/logger.rb",
30
35
  "runpuppet.gemspec",
36
+ "sh/c",
37
+ "sh/console.rb",
38
+ "sh/test",
39
+ "test/agent_test.rb",
40
+ "test/binary_test.rb",
41
+ "test/client_test.rb",
42
+ "test/config_test.rb",
43
+ "test/fixtures/runpuppet.yml",
44
+ "test/fixtures/shell/arp_eth0.txt",
45
+ "test/fixtures/shell/ip_addr_list_eth0.txt",
31
46
  "test/helper.rb"
32
47
  ]
33
48
  s.homepage = "http://github.com/dawanda/runpuppet"
data/sh/c ADDED
@@ -0,0 +1 @@
1
+ irb -r sh/console.rb
data/sh/console.rb ADDED
@@ -0,0 +1,14 @@
1
+
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'runpuppet'
data/sh/test ADDED
@@ -0,0 +1 @@
1
+ rake test
@@ -0,0 +1,49 @@
1
+ require 'test/helper'
2
+
3
+ describe "Runpuppet::Agent" do
4
+ before do
5
+ @agent = TestContext.agent
6
+ end
7
+
8
+ describe :check_status do
9
+ it "returns the action for puppet and branch" do
10
+ @agent.stubs(:get).returns('run-master')
11
+ @agent.check_status.must_equal ["run", "master"]
12
+ end
13
+ end
14
+
15
+ describe :base_url do
16
+ it 'works' do
17
+ @agent.base_url('/action').must_equal "http://user:pass@puppet.example.com/action"
18
+ end
19
+ end
20
+
21
+ describe "URL manipulation" do
22
+ before do
23
+ TestContext.config.stubs(:local_ip).returns('10.10.10.10')
24
+ TestContext.config.stubs(:hostname).returns('example-vm')
25
+ end
26
+
27
+
28
+ describe :append_params_to_post do
29
+ it "adds hostname and local ip to params" do
30
+ params = {}
31
+ new_params = @agent.append_params_to_post(params)
32
+ new_params[:hostname].must_equal 'example-vm'
33
+ new_params[:ip].must_equal '10.10.10.10'
34
+ end
35
+ end
36
+
37
+ describe :append_params_to_url do
38
+ it "adds ip and hostname to url" do
39
+ new_url = @agent.append_params_to_url('/action')
40
+ new_url.must_equal "/action?hostname=example-vm&ip=10.10.10.10"
41
+ end
42
+
43
+ it "appends to existing params, if needed" do
44
+ new_url = @agent.append_params_to_url('/action?some_funny_param=1')
45
+ new_url.must_equal "/action?some_funny_param=1&hostname=example-vm&ip=10.10.10.10"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ require 'test/helper'
2
+ describe "Runpuppet" do
3
+ it "has no syntax errors" do
4
+ a = %x(./bin/runpuppet -h 2>&1)
5
+ a.must_match 'Runpuppet for puppet_controller'
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/helper'
2
+
3
+ describe "Client" do
4
+ before do
5
+ @ctx = Dim::Container.new(TestContext)
6
+ end
7
+
8
+ describe :run_command do
9
+ it "without --verbose param" do
10
+ cmd = "cd /etc/puppet/repo && git fetch && git checkout -f origin/feature && puppet apply /etc/puppet/repo/manifests/site.pp"
11
+ @ctx.client.run_command('feature').must_equal cmd
12
+ end
13
+
14
+ it "with --verbose param" do
15
+ @ctx.register(:run_options){ {:verbose => true} }
16
+ cmd = "cd /etc/puppet/repo && git fetch && git checkout -f origin/feature && /etc/puppet/repo/bin/prepare_environment.rb && puppet apply -v /etc/puppet/repo/manifests/site.pp"
17
+ @ctx.client.run_command('feature').must_equal cmd
18
+ end
19
+ end
20
+
21
+ describe :should_run? do
22
+ it "always runs without --try option" do
23
+ @ctx.register(:run_options){ {:try => false} }
24
+ @ctx.client.should_run?('branch_does_not_matter').must_equal true
25
+ end
26
+
27
+ it "runs with --try option only for 'run' action" do
28
+ @ctx.register(:run_options){ {:try => true} }
29
+ @ctx.client.should_run?('run').must_equal true
30
+ end
31
+
32
+ it "does not run with --try option, if not 'run' action" do
33
+ @ctx.register(:run_options){ {:try => true} }
34
+ @ctx.client.should_run?('some_random_action').must_equal false
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,89 @@
1
+ require 'test/helper'
2
+
3
+ describe 'Config' do
4
+ def shell_fixture(path)
5
+ File.read("test/fixtures/shell/#{path}").strip
6
+ end
7
+
8
+ before do
9
+ @config = TestContext.config
10
+ end
11
+
12
+ it "reports facts" do
13
+ ec2_facts = [["architecture", "x86_64"], ["arp", "fe:ff:ff:ff:ff:ff"], ["arp_eth0", "fe:ff:ff:ff:ff:ff"], ["domain", "eu-west-1.compute.internal"], ["ec2_ami_id", "ami-7acafc0e"], ["ec2_ami_launch_index", "0"], ["ec2_ami_manifest_path", "(unknown)"], ["ec2_block_device_mapping_ami", "/dev/sda1"], ["ec2_block_device_mapping_ephemeral0", "/dev/sdb"], ["ec2_block_device_mapping_root", "/dev/sda1"], ["ec2_hostname", "ip-10-234-151-254.eu-west-1.compute.internal"], ["ec2_instance_id", "i-cc511dba"], ["ec2_instance_type", "t1.micro"], ["ec2_kernel_id", "aki-4feec43b"], ["ec2_local_hostname", "ip-10-234-151-254.eu-west-1.compute.internal"], ["ec2_local_ipv4", "10.234.151.254"], ["ec2_placement_availability_zone", "eu-west-1a"], ["ec2_profile", "default-paravirtual"], ["ec2_public_hostname", "ec2-46-137-37-20.eu-west-1.compute.amazonaws.com"], ["ec2_public_ipv4", "46.137.37.20"], ["ec2_public_keys_0_openssh_key", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCn6ld1os3dZkdIjJ0zqOUrZWi9zODc2WEaonlPRjyxqhX5nDYJMFrvKRXAIi41TKxwGXzor55gbLb5GnLDFMHEZwtye9MH4n98DdSFu8Nxb9wZgT1xZ+UE/9+GKVAJq77yIWP5qe6iJe80JQAaO/WbinMoqBZ9YOF2MgPNIUoP/bPHZ6Fb+/3Nv1NV+aAMB2vqOlrujcGkI49vFmH6qbNKgAAyuakGSIlBab4PBPti3B+tOoLeimqL4H8iAQAWZCjinG12oUTkl07ZpU1waFUTDaKv4QvwFU4bGgZYk7hysAjE7A8NxI7ApEenbxySnkjew4zQlmPmV21u16E3kGYx node-autoscaling"], ["ec2_reservation_id", "r-7c31b10a"], ["ec2_security_groups", "default"], ["facterversion", "1.5.9"], ["fqdn", "ip-10-234-151-254.eu-west-1.compute.internal"], ["hardwareisa", "unknown"], ["hardwaremodel", "x86_64"], ["hostname", "ip-10-234-151-254"], ["id", "root"], ["interfaces", "dummy0,eql,eth0,ifb0,ifb1,lo"], ["ipaddress", "10.234.151.254"], ["ipaddress_eth0", "10.234.151.254"], ["ipaddress_lo", "127.0.0.1"], ["is_virtual", "true"], ["kernel", "Linux"], ["kernelmajversion", "2.6"], ["kernelrelease", "2.6.32-314-ec2"], ["kernelversion", "2.6.32"], ["lib", "/var/lib/puppet/facts"], ["lsbdistcodename", "lucid"], ["lsbdistdescription", "Ubuntu 10.04.2 LTS"], ["lsbdistid", "Ubuntu"], ["lsbdistrelease", "10.04"], ["lsbmajdistrelease", "10"], ["macaddress", "26:73:1b:a3:48:2a"], ["macaddress_dummy0", "26:73:1b:a3:48:2a"], ["macaddress_eth0", "12:31:3b:05:94:10"], ["macaddress_ifb0", "5e:5b:e7:92:26:c2"], ["macaddress_ifb1", "72:50:ad:1d:a1:0f"], ["memoryfree", "430.29 MB"], ["memorysize", "635.17 MB"], ["netmask", "255.255.254.0"], ["netmask_eth0", "255.255.254.0"], ["netmask_lo", "255.0.0.0"], ["network_eth0", "10.234.150.0"], ["network_lo", "127.0.0.0"], ["operatingsystem", "Ubuntu"], ["operatingsystemrelease", "10.04"], ["path", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/rvm/bin"], ["physicalprocessorcount", "1"], ["processor0", "Intel(R) Xeon(R) CPU E5430 @ 2.66GHz"], ["processorcount", "1"], ["ps", "ps -ef"], ["puppetversion", "2.6.7"], ["rubysitedir", "/usr/local/lib/ruby/site_ruby/1.8"], ["rubyversion", "1.8.7"], ["selinux", "false"], ["sshdsakey", "AAAAB3NzaC1kc3MAAACBAM2/DHTO3olTFG6lmWXNJcEYKZtFylFWCLJomNEaMMkf7qEtCLSPVWdhgYKHmk/UBPrpuzWrapVa1/eap77CNgQ6e8LmKdcgkCVcuKSLqtm+e989lb9RrcIUYYd4UXIZbLPKF3z3AOmESxikaiQs9M8x4Jn5kmpPb6fixSvOi577AAAAFQDAQMxsywSbD3W28MCI3kfrbKhEPwAAAIBm5HQwsY8VZnfLgWdkpZfcDv2V/9U+0+Atd6O37wpmF4HjIqbIbTJ1ABCXhLgo5oX2YVsRWfVLLxsmgxPoF5CLBNPQcFhNldto4H8sGkcbNFU8oBEiOgnZ6ZEax/Ooe/bO7wR+dz0F5u9IuMj4QK1GWuiAUr7U8E9Ithhe3DVq1QAAAIB3xFxOwbewB9YaeajoTfJDZzt/ovgSD3V4YYgX7mRG8Zv5UW2LduLgifwBJLWVt/Qp44STI1wON2OFRNDvhIH82+5iW3m5ifIy5c8ZviupZVpYy2adw/Ay3+bP/w0TtosmlzyWW7tj2jXVTc79ul3y9uXfZcQw8EB0ISbafy6+2Q=="], ["sshrsakey", "AAAAB3NzaC1yc2EAAAABIwAAAQEAtdvq2CjLz74rL1peJiZakeZtgeJ6lQ1vzCHseSkB3kjsPBMckz9RIec0PrLcY7BmEMfTIJJOq8OrrKdeCauRWQ47tuajVtXr+FXB0U+4FRLs2onBzUI8k2ToY8qNR7TfD5MmirBrYb26S/r0Lm8d86RkkMl4snbwEU0b42e6NbzcjVShAkbGGols7FpziqQWZY4Coo4Z2b2IBLqBZXg4N9laAsR3NlH8JclkUZ34gh5Bnzmr6b/IxTR06aIP0s0W9KEmzuHGv7S/loC1xAgxJMZf/ViLGAGf83jpnp7mMJ5Pbtbbys8tv+Jp4Jobmn/90FkMstkxpoPZX48ImwDfbQ=="], ["swapfree", "0.00 kB"], ["swapsize", "0.00 kB"], ["timezone", "CEST"], ["uniqueid", "ea0afe97"], ["uptime", "4:51 hours"], ["uptime_days", 0], ["uptime_hours", 4], ["uptime_seconds", 17517], ["virtual", "xenu"]]
14
+ end
15
+
16
+ describe :local_ip do
17
+ it 'on ec2' do
18
+ @config.stubs(:is_ec2?).returns(true)
19
+ ## require factor or not?
20
+ #Facter.stubs(:value).with('ec2_public_ipv4').returns('x.x')
21
+ #@config.local_ip.must_equal 'xx'
22
+ end
23
+
24
+ it "from ip addr, if local_ip_interface" do
25
+ @config.stubs(:is_ec2?).returns(false)
26
+ @config.data['local_ip_interface'] = 'something'
27
+ @config.stubs(:parse_local_ip_from_interface).returns('x.x.x.x')
28
+ @config.local_ip.must_equal 'x.x.x.x'
29
+ end
30
+
31
+ describe 'otherwise' do
32
+ it "from local_ip, if present" do
33
+ @config.stubs(:is_ec2?).returns(false)
34
+ @config.data['local_ip_interface'] = nil
35
+ @config.data['local_ip'] = 'x.x.x.y'
36
+ @config.local_ip.must_equal 'x.x.x.y'
37
+ end
38
+
39
+ it "from ifconfig with 192.168.x.x regex" do
40
+
41
+ end
42
+ it "from ifconfig with 10.10.x.x regex" do
43
+
44
+ end
45
+ end
46
+ end
47
+
48
+ describe :hostname do
49
+ it 'read from socket' do
50
+ Socket.stubs(:gethostname).returns('some_host')
51
+ @config.hostname.must_equal 'some_host'
52
+ end
53
+ end
54
+
55
+ describe :is_ec2? do
56
+ it 'works' do
57
+ @config.stubs(:read_shell).returns(shell_fixture('arp_eth0.txt'))
58
+ @config.is_ec2?.must_be :>, 0
59
+ end
60
+ end
61
+
62
+ describe :parse_local_ip_from_interface do
63
+ it 'works' do
64
+ cmd = "ip addr list #{@config.data['local_ip_interface']}"
65
+ @config.stubs(:read_shell).with(cmd).returns(shell_fixture('ip_addr_list_eth0.txt'))
66
+ @config.parse_local_ip_from_interface.must_equal "10.10.10.10"
67
+ end
68
+ end
69
+
70
+ describe :puppet_controller_url do
71
+ it 'works' do
72
+ @config.puppet_controller_url.must_equal "http://user:pass@puppet.example.com"
73
+ end
74
+ end
75
+
76
+ describe "puppet_controller_auth" do
77
+ it "parses the auth info from url" do
78
+ @config.stubs(:puppet_controller_url).returns('http://user:pass@puppet.example.com')
79
+ "http://user:pass@puppet.example.com".must_equal(@config.puppet_controller_url)
80
+ ['user', 'pass'].must_equal(@config.puppet_controller_auth)
81
+ end
82
+ end
83
+
84
+ describe :lock_file do
85
+ it "defaults to /tmp/runpuppet.lock" do
86
+ @config.lock_file.must_equal "/tmp/runpuppet.lock"
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,7 @@
1
+ ---
2
+ puppet_controller_url: http://user:pass@puppet.example.com
3
+ command: 'cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && puppet apply /etc/puppet/repo/manifests/site.pp'
4
+ verbose_command: 'cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && /etc/puppet/repo/bin/prepare_environment.rb && puppet apply -v /etc/puppet/repo/manifests/site.pp'
5
+ branch: master
6
+ local_ip: 10.10.10.10
7
+ local_ip_interface: eth0
@@ -0,0 +1,2 @@
1
+ asdlkjalksdjlkj
2
+ fe:ff:ff:ff:ff
@@ -0,0 +1,5 @@
1
+ 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
2
+ link/ether 08:00:27:9f:ac:82 brd ff:ff:ff:ff:ff:ff
3
+ inet 10.10.10.10/24 scope host lo
4
+ inet6 fe80::a00:27ff:fe9f:ac82/64 scope link
5
+ valid_lft forever preferred_lft forever
data/test/helper.rb CHANGED
@@ -13,3 +13,35 @@ require 'mocha'
13
13
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
14
  $LOAD_PATH.unshift(File.dirname(__FILE__))
15
15
  require 'runpuppet'
16
+
17
+ def self.fixture_path(path)
18
+ "test/fixtures/#{path}"
19
+ end
20
+
21
+
22
+ def create_test_context(options={})
23
+ ctx = Dim::Container.new
24
+
25
+ ctx.register(:config) do
26
+ Runpuppet::Config.new(fixture_path('runpuppet.yml'))
27
+ end
28
+
29
+ ctx.register(:client) do |context|
30
+ Runpuppet::Client.new(context)
31
+ end
32
+
33
+ ctx.register(:agent) do |context|
34
+ Runpuppet::Agent.new(context)
35
+ end
36
+
37
+ ctx.register(:run_options) do
38
+ {}
39
+ end
40
+
41
+ ctx.register(:logger) do
42
+ Runpuppet::Logger
43
+ end
44
+ return ctx
45
+ end
46
+
47
+ TestContext = create_test_context({})
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runpuppet
3
3
  version: !ruby/object:Gem::Version
4
- hash: -3127271948
4
+ hash: 3495532457
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
10
  - rc
11
- - 1
12
- version: 1.0.0.rc1
11
+ - 2
12
+ version: 1.0.0.rc2
13
13
  platform: ruby
14
14
  authors:
15
15
  - Roman Heinrich
@@ -141,8 +141,23 @@ files:
141
141
  - Rakefile
142
142
  - VERSION
143
143
  - bin/runpuppet
144
+ - lib/ext/core.rb
144
145
  - lib/runpuppet.rb
146
+ - lib/runpuppet/agent.rb
147
+ - lib/runpuppet/client.rb
148
+ - lib/runpuppet/config.rb
149
+ - lib/runpuppet/logger.rb
145
150
  - runpuppet.gemspec
151
+ - sh/c
152
+ - sh/console.rb
153
+ - sh/test
154
+ - test/agent_test.rb
155
+ - test/binary_test.rb
156
+ - test/client_test.rb
157
+ - test/config_test.rb
158
+ - test/fixtures/runpuppet.yml
159
+ - test/fixtures/shell/arp_eth0.txt
160
+ - test/fixtures/shell/ip_addr_list_eth0.txt
146
161
  - test/helper.rb
147
162
  homepage: http://github.com/dawanda/runpuppet
148
163
  licenses: