runpuppet 1.0.0.rc1 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
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: