puppet 2.6.8 → 2.6.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (60) hide show
  1. data/CHANGELOG +41 -0
  2. data/{README.rst → README.md} +17 -10
  3. data/conf/redhat/puppet.spec +93 -22
  4. data/ext/vim/README +2 -1
  5. data/ext/vim/ftplugin/puppet.vim +94 -0
  6. data/ext/vim/indent/puppet.vim +76 -0
  7. data/lib/puppet.rb +2 -3
  8. data/lib/puppet/application/agent.rb +3 -3
  9. data/lib/puppet/application/apply.rb +16 -5
  10. data/lib/puppet/configurer.rb +60 -56
  11. data/lib/puppet/configurer/fact_handler.rb +6 -1
  12. data/lib/puppet/defaults.rb +19 -0
  13. data/lib/puppet/file_serving/fileset.rb +1 -1
  14. data/lib/puppet/indirector/exec.rb +3 -3
  15. data/lib/puppet/indirector/queue.rb +1 -1
  16. data/lib/puppet/metatype/manager.rb +7 -20
  17. data/lib/puppet/parser/compiler.rb +17 -16
  18. data/lib/puppet/parser/resource.rb +18 -1
  19. data/lib/puppet/parser/scope.rb +2 -2
  20. data/lib/puppet/provider/mount/parsed.rb +1 -1
  21. data/lib/puppet/provider/naginator.rb +9 -1
  22. data/lib/puppet/provider/nameservice/directoryservice.rb +11 -8
  23. data/lib/puppet/provider/package/aptitude.rb +1 -0
  24. data/lib/puppet/rails/host.rb +7 -0
  25. data/lib/puppet/resource/catalog.rb +9 -3
  26. data/lib/puppet/transaction.rb +15 -26
  27. data/lib/puppet/transaction/report.rb +3 -3
  28. data/lib/puppet/type.rb +13 -24
  29. data/lib/puppet/util/queue.rb +1 -1
  30. data/lib/puppet/util/queue/stomp.rb +2 -2
  31. data/lib/puppet/util/settings/file_setting.rb +1 -0
  32. data/spec/integration/defaults_spec.rb +22 -0
  33. data/spec/integration/indirector/catalog/queue_spec.rb +2 -2
  34. data/spec/integration/type_spec.rb +11 -0
  35. data/spec/unit/application/agent_spec.rb +2 -2
  36. data/spec/unit/application/apply_spec.rb +62 -50
  37. data/spec/unit/configurer/fact_handler_spec.rb +43 -37
  38. data/spec/unit/configurer_spec.rb +404 -327
  39. data/spec/unit/file_serving/fileset_spec.rb +7 -0
  40. data/spec/unit/indirector/exec_spec.rb +4 -4
  41. data/spec/unit/indirector/node/exec_spec.rb +1 -1
  42. data/spec/unit/indirector/queue_spec.rb +4 -4
  43. data/spec/unit/node_spec.rb +1 -0
  44. data/spec/unit/parser/compiler_spec.rb +8 -46
  45. data/spec/unit/parser/resource_spec.rb +61 -3
  46. data/spec/unit/parser/scope_spec.rb +9 -3
  47. data/spec/unit/provider/nameservice/directoryservice_spec.rb +60 -0
  48. data/spec/unit/rails/host_spec.rb +8 -0
  49. data/spec/unit/resource/catalog_spec.rb +1 -1
  50. data/spec/unit/transaction/report_spec.rb +3 -3
  51. data/spec/unit/transaction_spec.rb +8 -2
  52. data/spec/unit/type_spec.rb +66 -0
  53. data/spec/unit/util/queue/stomp_spec.rb +10 -10
  54. data/spec/unit/util/settings/file_setting_spec.rb +4 -0
  55. metadata +1229 -1232
  56. data/README +0 -31
  57. data/lib/puppet/provider/nameservice/#directoryservice.rb# +0 -519
  58. data/lib/puppet/reference/#providers.rb# +0 -123
  59. data/spec/unit/indirector/certificate_status/#file_spec.rb# +0 -188
  60. data/spec/unit/resource/#type_collection_spec.rb# +0 -463
@@ -1,123 +0,0 @@
1
- # This doesn't get stored in trac, since it changes every time.
2
- providers = Puppet::Util::Reference.newreference :providers, :title => "Provider Suitability Report", :depth => 1, :dynamic => true, :doc => "Which providers are valid for this machine" do
3
- types = []
4
- newPuppet::Type.loadall
5
- Puppet::Type.eachtype do |klass|
6
- next unless klass.providers.length > 0
7
- types << klass
8
- end
9
- types.sort! { |a,b| a.name.to_s <=> b.name.to_s }
10
-
11
- command_line = Puppet::Util::CommandLine.new
12
- types.reject! { |type| ! command_line.args.include?(type.name.to_s) } unless command_line.args.empty?
13
-
14
- ret = "Details about this host:\n\n"
15
-
16
- # Throw some facts in there, so we know where the report is from.
17
- ["Ruby Version", "Puppet Version", "Operating System", "Operating System Release"].each do |label|
18
- name = label.gsub(/\s+/, '')
19
- value = Facter.value(name)
20
- ret += option(label, value)
21
- end
22
- ret += "\n"
23
-
24
- count = 1
25
-
26
- # Produce output for each type.
27
- types.each do |type|
28
- features = type.features
29
- ret += "\n" # add a trailing newline
30
-
31
- # Now build up a table of provider suitability.
32
- headers = %w{Provider Suitable?} + features.collect { |f| f.to_s }.sort
33
-
34
- table_data = {}
35
-
36
- functional = false
37
- notes = []
38
- begin
39
- default = type.defaultprovider.name
40
- rescue Puppet::DevError
41
- default = "none"
42
- end
43
- type.providers.sort { |a,b| a.to_s <=> b.to_s }.each do |pname|
44
- data = []
45
- table_data[pname] = data
46
- provider = type.provider(pname)
47
-
48
- # Add the suitability note
49
- if missing = provider.suitable?(false) and missing.empty?
50
- data << "*X*"
51
- suit = true
52
- functional = true
53
- else
54
- data << "[#{count}]_" # A pointer to the appropriate footnote
55
- suit = false
56
- end
57
-
58
- # Add a footnote with the details about why this provider is unsuitable, if that's the case
59
- unless suit
60
- details = ".. [#{count}]\n"
61
- missing.each do |test, values|
62
- case test
63
- when :exists
64
- details += " - Missing files #{values.join(", ")}\n"
65
- when :variable
66
- values.each do |name, facts|
67
- if Puppet.settings.valid?(name)
68
- details += " - Setting #{name} (currently #{Puppet.settings.value(name).inspect}) not in list #{facts.join(", ")}\n"
69
- else
70
- details += " - Fact #{name} (currently #{Facter.value(name).inspect}) not in list #{facts.join(", ")}\n"
71
- end
72
- end
73
- when :true
74
- details += " - Got #{values} true tests that should have been false\n"
75
- when :false
76
- details += " - Got #{values} false tests that should have been true\n"
77
- when :feature
78
- details += " - Missing features #{values.collect { |f| f.to_s }.join(",")}\n"
79
- end
80
- end
81
- notes << details
82
-
83
- count += 1
84
- end
85
-
86
- # Add a note for every feature
87
- features.each do |feature|
88
- if provider.features.include?(feature)
89
- data << "*X*"
90
- else
91
- data << ""
92
- end
93
- end
94
- end
95
-
96
- ret += h(type.name.to_s + "_", 2)
97
-
98
- ret += "[#{type.name}](#{"http://docs.puppetlabs.com/references/stable/type.html##{type.name}"})\n\n"
99
- ret += option("Default provider", default)
100
- ret += doctable(headers, table_data)
101
-
102
- notes.each do |note|
103
- ret += note + "\n"
104
- end
105
-
106
- ret += "\n"
107
- end
108
-
109
- ret += "\n"
110
-
111
- ret
112
- end
113
- providers.header = "
114
- Puppet resource types are usually backed by multiple implementations called `providers`,
115
- which handle variance between platforms and tools.
116
-
117
- Different providers are suitable or unsuitable on different platforms based on things
118
- like the presence of a given tool.
119
-
120
- Here are all of the provider-backed types and their different providers. Any unmentioned
121
- types do not use providers yet.
122
-
123
- "
@@ -1,188 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper.rb')
4
- require 'puppet/ssl/host'
5
- require 'puppet/indirector/certificate_status'
6
- require 'tempfile'
7
-
8
- describe "Puppet::Indirector::CertificateStatus::File" do
9
- include PuppetSpec::Files
10
-
11
- before do
12
- Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
13
- @terminus = Puppet::SSL::Host.indirection.terminus(:file)
14
-
15
- @tmpdir = tmpdir("certificate_status_ca_testing")
16
- Puppet[:confdir] = @tmpdir
17
- Puppet[:vardir] = @tmpdir
18
-
19
- # localcacert is where each client stores the CA certificate
20
- # cacert is where the master stores the CA certificate
21
- # Since we need to play the role of both for testing we need them to be the same and exist
22
- Puppet[:cacert] = Puppet[:localcacert]
23
- end
24
-
25
- def generate_csr(host)
26
- host.generate_key
27
- csr = Puppet::SSL::CertificateRequest.new(host.name)
28
- csr.generate(host.key.content)
29
- Puppet::SSL::CertificateRequest.indirection.save(csr)
30
- end
31
-
32
- def sign_csr(host)
33
- host.desired_state = "signed"
34
- @terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
35
- end
36
-
37
- def generate_signed_cert(host)
38
- generate_csr(host)
39
- sign_csr(host)
40
-
41
- @terminus.find(Puppet::Indirector::Request.new(:certificate_status, :find, host.name, host))
42
- end
43
-
44
- def generate_revoked_cert(host)
45
- generate_signed_cert(host)
46
-
47
- host.desired_state = "revoked"
48
-
49
- @terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
50
- end
51
-
52
- it "should be a terminus on SSL::Host" do
53
- @terminus.should be_instance_of(Puppet::Indirector::CertificateStatus::File)
54
- end
55
-
56
- it "should create a CA instance if none is present" do
57
- @terminus.ca.should be_instance_of(Puppet::SSL::CertificateAuthority)
58
- end
59
-
60
- describe "when creating the CA" do
61
- it "should fail if it is not a valid CA" do
62
- Puppet::SSL::CertificateAuthority.expects(:ca?).returns false
63
- lambda { @terminus.ca }.should raise_error(ArgumentError, "This process is not configured as a certificate authority")
64
- end
65
- end
66
-
67
- it "should be indirected with the name 'certificate_status'" do
68
- Puppet::SSL::Host.indirection.name.should == :certificate_status
69
- end
70
-
71
- describe "when finding" do
72
- before do
73
- @host = Puppet::SSL::Host.new("foo")
74
- Puppet.settings.use(:main)
75
- end
76
-
77
- it "should return the Puppet::SSL::Host when a CSR exists for the host" do
78
- generate_csr(@host)
79
- request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
80
-
81
- retrieved_host = @terminus.find(request)
82
-
83
- retrieved_host.name.should == @host.name
84
- retrieved_host.certificate_request.content.to_s.chomp.should == @host.certificate_request.content.to_s.chomp
85
- end
86
-
87
- it "should return the Puppet::SSL::Host when a public key exist for the host" do
88
- generate_signed_cert(@host)
89
- request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
90
-
91
- retrieved_host = @terminus.find(request)
92
-
93
- retrieved_host.name.should == @host.name
94
- retrieved_host.certificate.content.to_s.chomp.should == @host.certificate.content.to_s.chomp
95
- end
96
-
97
- it "should return nil when neither a CSR nor public key exist for the host" do
98
- request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
99
- @terminus.find(request).should == nil
100
- end
101
- end
102
-
103
- describe "when saving" do
104
- before do
105
- @host = Puppet::SSL::Host.new("foobar")
106
- Puppet.settings.use(:main)
107
- end
108
-
109
- describe "when signing a cert" do
110
- before do
111
- @host.desired_state = "signed"
112
- @request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
113
- end
114
-
115
- it "should fail if no CSR is on disk" do
116
- lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /certificate request/)
117
- end
118
-
119
- it "should sign the on-disk CSR when it is present" do
120
- signed_host = generate_signed_cert(@host)
121
-
122
- signed_host.state.should == "signed"
123
- Puppet::SSL::Certificate.indirection.find("foobar").should be_instance_of(Puppet::SSL::Certificate)
124
- end
125
- end
126
-
127
- describe "when revoking a cert" do
128
- before do
129
- @request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
130
- end
131
-
132
- it "should fail if no certificate is on disk" do
133
- @host.desired_state = "revoked"
134
- lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /Cannot revoke/)
135
- end
136
-
137
- it "should revoke the certificate when it is present" do
138
- generate_revoked_cert(@host)
139
-
140
- @host.state.should == 'revoked'
141
- end
142
- end
143
- end
144
-
145
- describe "when deleting" do
146
- before do
147
- Puppet.settings.use(:main)
148
- end
149
-
150
- it "should not delete anything if no certificate, request, or key is on disk" do
151
- host = Puppet::SSL::Host.new("clean_me")
152
- request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_me", host)
153
- @terminus.destroy(request).should == "Nothing was deleted"
154
- end
155
-
156
- it "should clean certs, cert requests, keys" do
157
- signed_host = Puppet::SSL::Host.new("clean_signed_cert")
158
- generate_signed_cert(signed_host)
159
- signed_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_signed_cert", signed_host)
160
- @terminus.destroy(signed_request).should == "Deleted for host clean_signed_cert: Puppet::SSL::Certificate, Puppet::SSL::Key"
161
-
162
- requested_host = Puppet::SSL::Host.new("clean_csr")
163
- generate_csr(requested_host)
164
- csr_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_csr", requested_host)
165
- @terminus.destroy(csr_request).should == "Deleted for 'host clean_signed_cert': Puppet::SSL::CertificateRequest, Puppet::SSL::Key"
166
- end
167
- end
168
-
169
- describe "when searching" do
170
- it "should return a list of all hosts with certificate requests, signed certs, or revoked certs" do
171
- Puppet.settings.use(:main)
172
-
173
- signed_host = Puppet::SSL::Host.new("signed_host")
174
- generate_signed_cert(signed_host)
175
-
176
- requested_host = Puppet::SSL::Host.new("requested_host")
177
- generate_csr(requested_host)
178
-
179
- revoked_host = Puppet::SSL::Host.new("revoked_host")
180
- generate_revoked_cert(revoked_host)
181
-
182
- retrieved_hosts = @terminus.search(Puppet::Indirector::Request.new(:certificate_status, :search, "all", signed_host))
183
-
184
- results = retrieved_hosts.map {|h| [h.name, h.state]}.sort{ |h,i| h[0] <=> i[0] }
185
- results.should == [["ca","signed"],["requested_host","requested"],["revoked_host","revoked"],["signed_host","signed"]]
186
- end
187
- end
188
- end
@@ -1,463 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.dirname(__FILE__) + '/../../spec_helper'
4
-
5
- require 'puppet/resource/type_collection'
6
- require 'puppet/resource/type'
7
-
8
- describe Puppet::Resource::TypeCollection do
9
- include PuppetSpec::Files
10
- before do
11
- @instance = Puppet::Resource::Type.new(:hostclass, "foo")
12
- @code = Puppet::Resource::TypeCollection.new("env")
13
- end
14
-
15
- it "should require an environment at initialization" do
16
- env = Puppet::Node::Environment.new("testing")
17
- Puppet::Resource::TypeCollection.new(env).environment.should equal(env)
18
- end
19
-
20
- it "should convert the environment into an environment instance if a string is provided" do
21
- env = Puppet::Node::Environment.new("testing")
22
- Puppet::Resource::TypeCollection.new("testing").environment.should equal(env)
23
- end
24
-
25
- it "should create a 'loader' at initialization" do
26
- Puppet::Resource::TypeCollection.new("testing").loader.should be_instance_of(Puppet::Parser::TypeLoader)
27
- end
28
-
29
- it "should be able to add a resource type" do
30
- Puppet::Resource::TypeCollection.new("env").should respond_to(:add)
31
- end
32
-
33
- it "should consider '<<' to be an alias to 'add' but should return self" do
34
- loader = Puppet::Resource::TypeCollection.new("env")
35
- loader.expects(:add).with "foo"
36
- loader.expects(:add).with "bar"
37
- loader << "foo" << "bar"
38
- end
39
-
40
- it "should set itself as the code collection for added resource types" do
41
- loader = Puppet::Resource::TypeCollection.new("env")
42
-
43
- node = Puppet::Resource::Type.new(:node, "foo")
44
-
45
- @code.add(node)
46
- @code.node("foo").should equal(node)
47
-
48
- node.resource_type_collection.should equal(@code)
49
- end
50
-
51
- it "should store node resource types as nodes" do
52
- node = Puppet::Resource::Type.new(:node, "foo")
53
-
54
- @code.add(node)
55
- @code.node("foo").should equal(node)
56
- end
57
-
58
- it "should store hostclasses as hostclasses" do
59
- klass = Puppet::Resource::Type.new(:hostclass, "foo")
60
-
61
- @code.add(klass)
62
- @code.hostclass("foo").should equal(klass)
63
- end
64
-
65
- it "should store definitions as definitions" do
66
- define = Puppet::Resource::Type.new(:definition, "foo")
67
-
68
- @code.add(define)
69
- @code.definition("foo").should equal(define)
70
- end
71
-
72
- it "should merge new classes with existing classes of the same name" do
73
- loader = Puppet::Resource::TypeCollection.new("env")
74
- first = Puppet::Resource::Type.new(:hostclass, "foo")
75
- second = Puppet::Resource::Type.new(:hostclass, "foo")
76
- loader.add first
77
- first.expects(:merge).with(second)
78
- loader.add(second)
79
- end
80
-
81
- it "should remove all nodes, classes, and definitions when cleared" do
82
- loader = Puppet::Resource::TypeCollection.new("env")
83
- loader.add Puppet::Resource::Type.new(:hostclass, "class")
84
- loader.add Puppet::Resource::Type.new(:definition, "define")
85
- loader.add Puppet::Resource::Type.new(:node, "node")
86
-
87
- loader.clear
88
- loader.hostclass("class").should be_nil
89
- loader.definition("define").should be_nil
90
- loader.node("node").should be_nil
91
- end
92
-
93
- describe "when looking up names" do
94
- before do
95
- @type = Puppet::Resource::Type.new(:hostclass, "ns::klass")
96
- end
97
-
98
- it "should support looking up with multiple namespaces" do
99
- @code.add @type
100
- @code.find_hostclass(%w{boo baz ns}, "klass").should equal(@type)
101
- end
102
-
103
- it "should not attempt to import anything when the type is already defined" do
104
- @code.add @type
105
- @code.loader.expects(:import).never
106
- @code.find_hostclass(%w{ns}, "klass").should equal(@type)
107
- end
108
-
109
- describe "that need to be loaded" do
110
- it "should use the loader to load the files" do
111
- @code.loader.expects(:load_until).with(["ns"], "klass")
112
- @code.find_or_load(["ns"], "klass", :hostclass)
113
- end
114
-
115
- it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do
116
- @code.loader.expects(:load_until).with(["ns"], "klass")
117
- @code.find_or_load("Ns", "Klass", :hostclass)
118
- end
119
-
120
- it "should attempt to find the type when the loader yields" do
121
- @code.loader.expects(:load_until).yields
122
- @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true)
123
- @code.find_or_load("ns", "klass", :hostclass)
124
- end
125
-
126
- it "should return the result of 'load_until'" do
127
- @code.loader.expects(:load_until).returns "foo"
128
- @code.find_or_load("Ns", "Klass", :hostclass).should == "foo"
129
- end
130
-
131
- it "should return nil if the name isn't found" do
132
- @code.stubs(:load_until).returns(nil)
133
- @code.find_or_load("Ns", "Klass", :hostclass).should be_nil
134
- end
135
- end
136
- end
137
-
138
- %w{hostclass node definition}.each do |data|
139
- before do
140
- @instance = Puppet::Resource::Type.new(data, "foo")
141
- end
142
-
143
- it "should have a method for adding a #{data}" do
144
- Puppet::Resource::TypeCollection.new("env").should respond_to("add_#{data}")
145
- end
146
-
147
- it "should use the name of the instance to add it" do
148
- loader = Puppet::Resource::TypeCollection.new("env")
149
- loader.send("add_#{data}", @instance)
150
- loader.send(data, @instance.name).should equal(@instance)
151
- end
152
-
153
- unless data == "hostclass"
154
- it "should fail to add a #{data} when one already exists" do
155
- loader = Puppet::Resource::TypeCollection.new("env")
156
- loader.add @instance
157
- lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
158
- end
159
- end
160
-
161
- it "should return the added #{data}" do
162
- loader = Puppet::Resource::TypeCollection.new("env")
163
-
164
- loader.add(@instance).should equal(@instance)
165
- end
166
-
167
- it "should be able to retrieve #{data} by name" do
168
- loader = Puppet::Resource::TypeCollection.new("env")
169
- instance = Puppet::Resource::Type.new(data, "bar")
170
- loader.add instance
171
- loader.send(data, "bar").should equal(instance)
172
- end
173
-
174
- it "should retrieve #{data} insensitive to case" do
175
- loader = Puppet::Resource::TypeCollection.new("env")
176
- instance = Puppet::Resource::Type.new(data, "Bar")
177
- loader.add instance
178
- loader.send(data, "bAr").should equal(instance)
179
- end
180
-
181
- it "should return nil when asked for a #{data} that has not been added" do
182
- Puppet::Resource::TypeCollection.new("env").send(data, "foo").should be_nil
183
- end
184
-
185
- it "should be able to retrieve all #{data}s" do
186
- plurals = { "hostclass" => "hostclasses", "node" => "nodes", "definition" => "definitions" }
187
- loader = Puppet::Resource::TypeCollection.new("env")
188
- instance = Puppet::Resource::Type.new(data, "foo")
189
- loader.add instance
190
- loader.send(plurals[data]).should == { "foo" => instance }
191
- end
192
- end
193
-
194
- describe "when finding a qualified instance" do
195
- it "should return any found instance if the instance name is fully qualified" do
196
- loader = Puppet::Resource::TypeCollection.new("env")
197
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
198
- loader.add instance
199
- loader.find("namespace", "::foo::bar", :hostclass).should equal(instance)
200
- end
201
-
202
- it "should return nil if the instance name is fully qualified and no such instance exists" do
203
- loader = Puppet::Resource::TypeCollection.new("env")
204
- loader.find("namespace", "::foo::bar", :hostclass).should be_nil
205
- end
206
-
207
- it "should be able to find classes in the base namespace" do
208
- loader = Puppet::Resource::TypeCollection.new("env")
209
- instance = Puppet::Resource::Type.new(:hostclass, "foo")
210
- loader.add instance
211
- loader.find("", "foo", :hostclass).should equal(instance)
212
- end
213
-
214
- it "should return the partially qualified object if it exists in a provided namespace" do
215
- loader = Puppet::Resource::TypeCollection.new("env")
216
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
217
- loader.add instance
218
- loader.find("foo", "bar::baz", :hostclass).should equal(instance)
219
- end
220
-
221
- it "should be able to find partially qualified objects in any of the provided namespaces" do
222
- loader = Puppet::Resource::TypeCollection.new("env")
223
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
224
- loader.add instance
225
- loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance)
226
- end
227
-
228
- it "should return the unqualified object if it exists in a provided namespace" do
229
- loader = Puppet::Resource::TypeCollection.new("env")
230
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
231
- loader.add instance
232
- loader.find("foo", "bar", :hostclass).should equal(instance)
233
- end
234
-
235
- it "should return the unqualified object if it exists in the parent namespace" do
236
- loader = Puppet::Resource::TypeCollection.new("env")
237
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar")
238
- loader.add instance
239
- loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance)
240
- end
241
-
242
- it "should should return the partially qualified object if it exists in the parent namespace" do
243
- loader = Puppet::Resource::TypeCollection.new("env")
244
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
245
- loader.add instance
246
- loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance)
247
- end
248
-
249
- it "should return the qualified object if it exists in the root namespace" do
250
- loader = Puppet::Resource::TypeCollection.new("env")
251
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
252
- loader.add instance
253
- loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance)
254
- end
255
-
256
- it "should return nil if the object cannot be found" do
257
- loader = Puppet::Resource::TypeCollection.new("env")
258
- instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
259
- loader.add instance
260
- loader.find("foo::bar", "eh", :hostclass).should be_nil
261
- end
262
-
263
- describe "when topscope has a class that has the same name as a local class" do
264
- before do
265
- @loader = Puppet::Resource::TypeCollection.new("env")
266
- [ "foo::bar", "bar" ].each do |name|
267
- @loader.add Puppet::Resource::Type.new(:hostclass, name)
268
- end
269
- end
270
-
271
- it "should favor the local class, if the name is unqualified" do
272
- @loader.find("foo", "bar", :hostclass).name.should == 'foo::bar'
273
- end
274
-
275
- it "should only look in the topclass, if the name is qualified" do
276
- @loader.find("foo", "::bar", :hostclass).name.should == 'bar'
277
- end
278
-
279
- end
280
-
281
- it "should not look in the local scope for classes when the name is qualified" do
282
- @loader = Puppet::Resource::TypeCollection.new("env")
283
- @loader.add Puppet::Resource::Type.new(:hostclass, "foo::bar")
284
-
285
- @loader.find("foo", "::bar", :hostclass).should == nil
286
- end
287
-
288
- end
289
-
290
- it "should use the generic 'find' method with an empty namespace to find nodes" do
291
- loader = Puppet::Resource::TypeCollection.new("env")
292
- loader.expects(:find).with("", "bar", :node)
293
- loader.find_node(stub("ignored"), "bar")
294
- end
295
-
296
- it "should use the 'find_or_load' method to find hostclasses" do
297
- loader = Puppet::Resource::TypeCollection.new("env")
298
- loader.expects(:find_or_load).with("foo", "bar", :hostclass)
299
- loader.find_hostclass("foo", "bar")
300
- end
301
-
302
- it "should use the 'find_or_load' method to find definitions" do
303
- loader = Puppet::Resource::TypeCollection.new("env")
304
- loader.expects(:find_or_load).with("foo", "bar", :definition)
305
- loader.find_definition("foo", "bar")
306
- end
307
-
308
- it "should indicate whether any nodes are defined" do
309
- loader = Puppet::Resource::TypeCollection.new("env")
310
- loader.add_node(Puppet::Resource::Type.new(:node, "foo"))
311
- loader.should be_nodes
312
- end
313
-
314
- it "should indicate whether no nodes are defined" do
315
- Puppet::Resource::TypeCollection.new("env").should_not be_nodes
316
- end
317
-
318
- describe "when finding nodes" do
319
- before :each do
320
- @loader = Puppet::Resource::TypeCollection.new("env")
321
- end
322
-
323
- it "should return any node whose name exactly matches the provided node name" do
324
- node = Puppet::Resource::Type.new(:node, "foo")
325
- @loader << node
326
-
327
- @loader.node("foo").should equal(node)
328
- end
329
-
330
- it "should return the first regex node whose regex matches the provided node name" do
331
- node1 = Puppet::Resource::Type.new(:node, /\w/)
332
- node2 = Puppet::Resource::Type.new(:node, /\d/)
333
- @loader << node1 << node2
334
-
335
- @loader.node("foo10").should equal(node1)
336
- end
337
-
338
- it "should preferentially return a node whose name is string-equal over returning a node whose regex matches a provided name" do
339
- node1 = Puppet::Resource::Type.new(:node, /\w/)
340
- node2 = Puppet::Resource::Type.new(:node, "foo")
341
- @loader << node1 << node2
342
-
343
- @loader.node("foo").should equal(node2)
344
- end
345
- end
346
-
347
- describe "when managing files" do
348
- before do
349
- @loader = Puppet::Resource::TypeCollection.new("env")
350
- Puppet::Util::LoadedFile.stubs(:new).returns stub("watched_file")
351
- end
352
-
353
- it "should have a method for specifying a file should be watched" do
354
- @loader.should respond_to(:watch_file)
355
- end
356
-
357
- it "should have a method for determining if a file is being watched" do
358
- @loader.watch_file("/foo/bar")
359
- @loader.should be_watching_file("/foo/bar")
360
- end
361
-
362
- it "should use LoadedFile to watch files" do
363
- Puppet::Util::LoadedFile.expects(:new).with("/foo/bar").returns stub("watched_file")
364
- @loader.watch_file("/foo/bar")
365
- end
366
-
367
- it "should be considered stale if any files have changed" do
368
- file1 = stub 'file1', :changed? => false
369
- file2 = stub 'file2', :changed? => true
370
- Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
371
- @loader.watch_file("/foo/bar")
372
- @loader.watch_file("/other/bar")
373
-
374
- @loader.should be_stale
375
- end
376
-
377
- it "should not be considered stable if no files have changed" do
378
- file1 = stub 'file1', :changed? => false
379
- file2 = stub 'file2', :changed? => false
380
- Puppet::Util::LoadedFile.expects(:new).times(2).returns(file1).then.returns(file2)
381
- @loader.watch_file("/foo/bar")
382
- @loader.watch_file("/other/bar")
383
-
384
- @loader.should_not be_stale
385
- end
386
- end
387
-
388
- describe "when performing initial import" do
389
- before do
390
- @parser = Puppet::Parser::Parser.new("test")
391
- Puppet::Parser::Parser.stubs(:new).returns @parser
392
- @code = Puppet::Resource::TypeCollection.new("env")
393
- end
394
-
395
- it "should set the parser's string to the 'code' setting and parse if code is available" do
396
- Puppet.settings[:code] = "my code"
397
- @parser.expects(:string=).with "my code"
398
- @parser.expects(:parse)
399
- @code.perform_initial_import
400
- end
401
-
402
- it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
403
- filename = tmpfile('myfile')
404
- File.open(filename, 'w'){|f| }
405
- Puppet.settings[:manifest] = filename
406
- @parser.expects(:file=).with filename
407
- @parser.expects(:parse)
408
- @code.perform_initial_import
409
- end
410
-
411
- it "should pass the manifest file to the parser even if it does not exist on disk" do
412
- filename = tmpfile('myfile')
413
- Puppet.settings[:code] = ""
414
- Puppet.settings[:manifest] = filename
415
- @parser.expects(:file=).with(filename).once
416
- @parser.expects(:parse).once
417
- @code.perform_initial_import
418
- end
419
-
420
- it "should fail helpfully if there is an error importing" do
421
- File.stubs(:exist?).returns true
422
- @parser.expects(:parse).raises ArgumentError
423
- @parser.stubs(:file=)
424
- lambda { @code.perform_initial_import }.should raise_error(Puppet::Error)
425
- end
426
-
427
- it "should mark the type collection as needing a reparse when there is an error parsing" do
428
- @parser.expects(:parse).raises Puppet::ParseError.new("Syntax error at ...")
429
-
430
- lambda { @code.perform_initial_import }.should raise_error(Puppet::Error, /Syntax error at .../)
431
- @code.require_reparse?.should be_true
432
- end
433
- end
434
-
435
- describe "when determining the configuration version" do
436
- before do
437
- @code = Puppet::Resource::TypeCollection.new("env")
438
- end
439
-
440
- it "should default to the current time" do
441
- time = Time.now
442
-
443
- Time.stubs(:now).returns time
444
- @code.version.should == time.to_i
445
- end
446
-
447
- it "should use the output of the environment's config_version setting if one is provided" do
448
- @code.environment.stubs(:[]).with(:config_version).returns("/my/foo")
449
-
450
- Puppet::Util.expects(:execute).with(["/my/foo"]).returns "output\n"
451
- @code.version.should == "output"
452
- end
453
-
454
- it "should raise a puppet parser error if executing config_version fails" do
455
- @code.environment.stubs(:[]).with(:config_version).returns("test")
456
- Puppet::Util.expects(:execute).raises(Puppet::ExecutionFailure.new("msg"))
457
-
458
- lambda { @code.version }.should raise_error(Puppet::ParseError)
459
- end
460
-
461
- end
462
-
463
- end