puppet 7.12.1 → 7.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +13 -8
  4. data/ext/project_data.yaml +1 -1
  5. data/lib/puppet/application/lookup.rb +72 -24
  6. data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
  7. data/lib/puppet/defaults.rb +3 -1
  8. data/lib/puppet/file_serving/metadata.rb +3 -0
  9. data/lib/puppet/file_system/file_impl.rb +7 -7
  10. data/lib/puppet/file_system/jruby.rb +1 -1
  11. data/lib/puppet/file_system/path_pattern.rb +10 -15
  12. data/lib/puppet/file_system/uniquefile.rb +1 -1
  13. data/lib/puppet/file_system/windows.rb +4 -4
  14. data/lib/puppet/file_system.rb +1 -1
  15. data/lib/puppet/functions/versioncmp.rb +6 -2
  16. data/lib/puppet/graph/simple_graph.rb +2 -1
  17. data/lib/puppet/pops/parser/code_merger.rb +4 -4
  18. data/lib/puppet/pops/parser/egrammar.ra +2 -0
  19. data/lib/puppet/pops/parser/eparser.rb +574 -558
  20. data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
  21. data/lib/puppet/pops/validation/checker4_0.rb +7 -2
  22. data/lib/puppet/provider/service/init.rb +5 -4
  23. data/lib/puppet/ssl/verifier.rb +3 -1
  24. data/lib/puppet/transaction/persistence.rb +22 -12
  25. data/lib/puppet/type/file/data_sync.rb +1 -1
  26. data/lib/puppet/type/file/group.rb +8 -1
  27. data/lib/puppet/type/file/owner.rb +8 -1
  28. data/lib/puppet/type/user.rb +40 -38
  29. data/lib/puppet/util/json.rb +17 -0
  30. data/lib/puppet/util/log.rb +7 -2
  31. data/lib/puppet/util/monkey_patches.rb +26 -2
  32. data/lib/puppet/util/package.rb +25 -16
  33. data/lib/puppet/util/yaml.rb +11 -0
  34. data/lib/puppet/version.rb +1 -1
  35. data/lib/puppet.rb +1 -0
  36. data/locales/puppet.pot +115 -93
  37. data/man/man5/puppet.conf.5 +10 -2
  38. data/man/man8/puppet-agent.8 +1 -1
  39. data/man/man8/puppet-apply.8 +1 -1
  40. data/man/man8/puppet-catalog.8 +1 -1
  41. data/man/man8/puppet-config.8 +1 -1
  42. data/man/man8/puppet-describe.8 +1 -1
  43. data/man/man8/puppet-device.8 +1 -1
  44. data/man/man8/puppet-doc.8 +1 -1
  45. data/man/man8/puppet-epp.8 +1 -1
  46. data/man/man8/puppet-facts.8 +1 -1
  47. data/man/man8/puppet-filebucket.8 +1 -1
  48. data/man/man8/puppet-generate.8 +1 -1
  49. data/man/man8/puppet-help.8 +1 -1
  50. data/man/man8/puppet-lookup.8 +9 -6
  51. data/man/man8/puppet-module.8 +1 -1
  52. data/man/man8/puppet-node.8 +1 -1
  53. data/man/man8/puppet-parser.8 +1 -1
  54. data/man/man8/puppet-plugin.8 +1 -1
  55. data/man/man8/puppet-report.8 +1 -1
  56. data/man/man8/puppet-resource.8 +1 -1
  57. data/man/man8/puppet-script.8 +1 -1
  58. data/man/man8/puppet-ssl.8 +1 -1
  59. data/man/man8/puppet.8 +2 -2
  60. data/spec/fixtures/unit/forge/bacula.json +1 -1
  61. data/spec/integration/application/lookup_spec.rb +29 -6
  62. data/spec/integration/parser/pcore_resource_spec.rb +10 -0
  63. data/spec/shared_contexts/l10n.rb +5 -0
  64. data/spec/unit/application/lookup_spec.rb +131 -10
  65. data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
  66. data/spec/unit/file_system/uniquefile_spec.rb +7 -1
  67. data/spec/unit/file_system_spec.rb +34 -4
  68. data/spec/unit/forge/module_release_spec.rb +3 -3
  69. data/spec/unit/functions/versioncmp_spec.rb +40 -4
  70. data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
  71. data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
  72. data/spec/unit/pops/validator/validator_spec.rb +5 -0
  73. data/spec/unit/provider/service/gentoo_spec.rb +6 -5
  74. data/spec/unit/provider/service/init_spec.rb +15 -9
  75. data/spec/unit/provider/service/openwrt_spec.rb +21 -29
  76. data/spec/unit/provider/service/redhat_spec.rb +3 -2
  77. data/spec/unit/transaction/persistence_spec.rb +51 -0
  78. data/spec/unit/type/file/group_spec.rb +7 -0
  79. data/spec/unit/type/file/owner_spec.rb +7 -0
  80. data/spec/unit/type/user_spec.rb +0 -45
  81. data/spec/unit/util/json_spec.rb +126 -0
  82. data/spec/unit/util/yaml_spec.rb +37 -13
  83. metadata +14 -4
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-GENERATE" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-GENERATE" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-generate\fR \- Generates Puppet code from Ruby definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-HELP" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-HELP" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-help\fR \- Display Puppet help\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-LOOKUP" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-LOOKUP" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-lookup\fR \- Interactive Hiera lookup
@@ -22,10 +22,7 @@ The most common version of this command is:
22
22
  puppet lookup [\-\-help] [\-\-type \fITYPESTRING\fR] [\-\-merge first|unique|hash|deep] [\-\-knock\-out\-prefix \fIPREFIX\-STRING\fR] [\-\-sort\-merged\-arrays] [\-\-merge\-hash\-arrays] [\-\-explain] [\-\-environment \fIENV\fR] [\-\-default \fIVALUE\fR] [\-\-node \fINODE\-NAME\fR] [\-\-facts \fIFILE\fR] [\-\-compile] [\-\-render\-as s|json|yaml|binary|msgpack] \fIkeys\fR
23
23
  .
24
24
  .SH "DESCRIPTION"
25
- The lookup command is a CLI for Puppet\'s \'lookup()\' function\. It searches your Hiera data and returns a value for the requested lookup key, so you can test and explore your data\. It is a modern replacement for the \'hiera\' command\.
26
- .
27
- .P
28
- Hiera usually relies on a node\'s facts to locate the relevant data sources\. By default, \'puppet lookup\' uses facts from the node you run the command on, but you can get data for any other node with the \'\-\-node \fINAME\fR\' option\. If possible, the lookup command will use the requested node\'s real stored facts from PuppetDB; if PuppetDB isn\'t configured or you want to provide arbitrary fact values, you can pass alternate facts as a JSON or YAML file with \'\-\-facts \fIFILE\fR\'\.
25
+ The lookup command is a CLI for Puppet\'s \'lookup()\' function\. It searches your Hiera data and returns a value for the requested lookup key, so you can test and explore your data\. It is a modern replacement for the \'hiera\' command\. Lookup uses the setting for global hiera\.yaml from puppet\'s config, and the environment to find the environment level hiera\.yaml as well as the resulting modulepath for the environment (for hiera\.yaml files in modules)\. Hiera usually relies on a node\'s facts to locate the relevant data sources\. By default, \'puppet lookup\' uses facts from the node you run the command on, but you can get data for any other node with the \'\-\-node \fINAME\fR\' option\. If possible, the lookup command will use the requested node\'s real stored facts from PuppetDB; if PuppetDB isn\'t configured or you want to provide arbitrary fact values, you can pass alternate facts as a JSON or YAML file with \'\-\-facts \fIFILE\fR\'\.
29
26
  .
30
27
  .P
31
28
  If you\'re debugging your Hiera data and want to see where values are coming from, use the \'\-\-explain\' option\.
@@ -54,7 +51,7 @@ For more details about how Hiera works, see the Hiera documentation: https://pup
54
51
  \-\-facts \fIFILE\fR Specify a \.json or \.yaml file of key => value mappings to override the facts for this lookup\. Any facts not specified in this file maintain their original value\.
55
52
  .
56
53
  .IP "\(bu" 4
57
- \-\-environment \fIENV\fR Like with most Puppet commands, you can specify an environment on the command line\. This is important for lookup because different environments can have different Hiera data\.
54
+ \-\-environment \fIENV\fR Like with most Puppet commands, you can specify an environment on the command line\. This is important for lookup because different environments can have different Hiera data\. This environment will be always be the one used regardless of any other factors\.
58
55
  .
59
56
  .IP "\(bu" 4
60
57
  \-\-merge first|unique|hash|deep: Specify the merge behavior, overriding any merge behavior from the data\'s lookup_options\. \'first\' returns the first value found\. \'unique\' appends everything to a merged, deduplicated array\. \'hash\' performs a simple hash merge by overwriting keys of lower lookup priority\. \'deep\' performs a deep merge on values of Array and Hash type\. There are additional options that can be used with \'deep\'\.
@@ -89,6 +86,12 @@ For more details about how Hiera works, see the Hiera documentation: https://pup
89
86
  To look up \'key_name\' using the Puppet Server node\'s facts: $ puppet lookup key_name
90
87
  .
91
88
  .P
89
+ To look up \'key_name\' using the Puppet Server node\'s arbitrary variables from a manifest, and classify the node if applicable: $ puppet lookup key_name \-\-compile
90
+ .
91
+ .P
92
+ To look up \'key_name\' using the Puppet Server node\'s facts, overridden by facts given in a file: $ puppet lookup key_name \-\-facts fact_file\.yaml
93
+ .
94
+ .P
92
95
  To look up \'key_name\' with agent\.local\'s facts: $ puppet lookup \-\-node agent\.local key_name
93
96
  .
94
97
  .P
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-MODULE" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-MODULE" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-module\fR \- Creates, installs and searches for modules on the Puppet Forge\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-NODE" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-NODE" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-node\fR \- View and manage node definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PARSER" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PARSER" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-parser\fR \- Interact directly with the parser\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PLUGIN" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PLUGIN" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-plugin\fR \- Interact with the Puppet plugin system\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-REPORT" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-REPORT" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-report\fR \- Create, display, and submit reports\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-RESOURCE" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-RESOURCE" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-resource\fR \- The resource abstraction layer shell
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SCRIPT" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SCRIPT" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-script\fR \- Run a puppet manifests as a script without compiling a catalog
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SSL" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SSL" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-ssl\fR \- Manage SSL keys and certificates for puppet SSL clients
data/man/man8/puppet.8 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET" "8" "October 2021" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET" "8" "December 2021" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\fR
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.12\.1
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.13\.0
@@ -37,7 +37,7 @@
37
37
  "license": "Apache 2.0",
38
38
  "checksums": { },
39
39
  "version": "0.0.2",
40
- "source": "git://github.com/puppetlabs/puppetlabs-bacula.git",
40
+ "source": "https://github.com/puppetlabs/puppetlabs-bacula",
41
41
  "project_page": "https://github.com/puppetlabs/puppetlabs-bacula",
42
42
  "summary": "bacula",
43
43
  "dependencies": [ ],
@@ -7,6 +7,7 @@ describe 'lookup' do
7
7
  include PuppetSpec::Files
8
8
 
9
9
  context 'with an environment' do
10
+ let(:fqdn) { Puppet.runtime[:facter].value(:fqdn) }
10
11
  let(:env_name) { 'spec' }
11
12
  let(:env_dir) { tmpdir('environments') }
12
13
  let(:environment_files) do
@@ -44,12 +45,19 @@ describe 'lookup' do
44
45
  let(:app) { Puppet::Application[:lookup] }
45
46
  let(:env) { Puppet::Node::Environment.create(env_name.to_sym, [File.join(populated_env_dir, env_name, 'modules')]) }
46
47
  let(:environments) { Puppet::Environments::Directories.new(populated_env_dir, []) }
48
+ let(:facts) { Puppet::Node::Facts.new("facts", {'my_fact' => 'my_fact_value'}) }
49
+ let(:cert) { pem_content('oid.pem') }
47
50
 
48
51
  let(:populated_env_dir) do
49
52
  dir_contained_in(env_dir, environment_files)
50
53
  env_dir
51
54
  end
52
55
 
56
+ before do
57
+ stub_request(:get, "https://puppet:8140/puppet-ca/v1/certificate/#{fqdn}").to_return(body: cert)
58
+ allow(Puppet::Node::Facts.indirection).to receive(:find).and_return(facts)
59
+ end
60
+
53
61
  def lookup(key, options = {}, explain = false)
54
62
  key = [key] unless key.is_a?(Array)
55
63
  allow(app.command_line).to receive(:args).and_return(key)
@@ -90,24 +98,39 @@ describe 'lookup' do
90
98
  expect(lookup('a')).to eql('value a')
91
99
  end
92
100
 
101
+ it 'loads trusted information from the node certificate' do
102
+ allow(Puppet).to receive(:override).and_call_original
103
+ expect(Puppet).to receive(:override).with(trusted_information: an_object_having_attributes(
104
+ certname: fqdn,
105
+ extensions: { "1.3.6.1.4.1.34380.1.2.1.1" => "somevalue" }))
106
+
107
+ lookup('a')
108
+ end
109
+
93
110
  it 'loads external facts when running without --node' do
94
111
  expect(Puppet::Util).not_to receive(:skip_external_facts)
95
112
  expect(Facter).not_to receive(:load_external)
96
113
  lookup('a')
97
114
  end
98
115
 
99
- it 'skip loading of external facts when run with --node' do
100
- app.options[:node] = "random_node"
101
- expect(Facter).to receive(:load_external).once.with(false)
102
- expect(Facter).to receive(:load_external).once.with(true)
103
- lookup('a')
116
+ describe 'when using --node' do
117
+ let(:fqdn) { 'random_node' }
118
+
119
+ it 'skips loading of external facts' do
120
+ app.options[:node] = fqdn
121
+
122
+ expect(Puppet::Node::Facts.indirection).to receive(:find).and_return(facts)
123
+ expect(Facter).to receive(:load_external).once.with(false)
124
+ expect(Facter).to receive(:load_external).once.with(true)
125
+ lookup('a')
126
+ end
104
127
  end
105
128
 
106
129
  context 'uses node_terminus' do
107
130
  require 'puppet/indirector/node/exec'
108
131
  require 'puppet/indirector/node/plain'
109
132
 
110
- let(:node) { Puppet::Node.new('testnode', :environment => env) }
133
+ let(:node) { Puppet::Node.new('testnode', :facts => facts, :environment => env) }
111
134
 
112
135
  it ':plain without --compile' do
113
136
  Puppet.settings[:node_terminus] = 'exec'
@@ -132,6 +132,16 @@ describe 'when pcore described resources types are in use' do
132
132
  expect(catalog.resource(:test1, "a").kind).to eq('compilable_type')
133
133
  end
134
134
 
135
+ it 'considers Pcore types to be builtin ' do
136
+ genface.types
137
+ catalog = compile_to_catalog(<<-MANIFEST)
138
+ test1 { 'a':
139
+ message => 'a works'
140
+ }
141
+ MANIFEST
142
+ expect(catalog.resource(:test1, "a").kind).to eq('compilable_type')
143
+ end
144
+
135
145
  it 'the validity of attribute names are checked' do
136
146
  genface.types
137
147
  expect do
@@ -4,7 +4,11 @@ RSpec.shared_context('l10n') do |locale|
4
4
  before :all do
5
5
  @old_locale = Locale.current
6
6
  Locale.current = locale
7
+
8
+ @old_gettext_disabled = Puppet::GettextConfig.instance_variable_get(:@gettext_disabled)
9
+ Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, false)
7
10
  Puppet::GettextConfig.setup_locale
11
+ Puppet::GettextConfig.create_default_text_domain
8
12
 
9
13
  # overwrite stubs with real implementation
10
14
  ::Object.send(:remove_method, :_)
@@ -17,6 +21,7 @@ RSpec.shared_context('l10n') do |locale|
17
21
  after :all do
18
22
  Locale.current = @old_locale
19
23
 
24
+ Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, @old_gettext_disabled)
20
25
  # restore stubs
21
26
  load File.expand_path(File.join(__dir__, '../../lib/puppet/gettext/stubs.rb'))
22
27
  end
@@ -518,34 +518,155 @@ Searching for "a"
518
518
  end
519
519
 
520
520
  it 'receives extra facts in top scope' do
521
- file_path = tmpdir('lookup_spec')
522
- filename = File.join(file_path, "facts.yaml")
523
- File.open(filename, "w+") { |f| f.write(<<-YAML.unindent) }
521
+ file_path = file_containing('facts.yaml', <<~CONTENT)
524
522
  ---
525
523
  cx: ' C from facts'
526
- YAML
524
+ CONTENT
527
525
 
528
526
  lookup.options[:node] = node
529
- lookup.options[:fact_file] = filename
527
+ lookup.options[:fact_file] = file_path
530
528
  lookup.options[:render_as] = :s
531
529
  allow(lookup.command_line).to receive(:args).and_return(['c'])
532
530
  expect(run_lookup(lookup)).to eql("This is C from facts")
533
531
  end
534
532
 
535
533
  it 'receives extra facts in the facts hash' do
536
- file_path = tmpdir('lookup_spec')
537
- filename = File.join(file_path, "facts.yaml")
538
- File.open(filename, "w+") { |f| f.write(<<-YAML.unindent) }
534
+ file_path = file_containing('facts.yaml', <<~CONTENT)
539
535
  ---
540
536
  cx: ' G from facts'
541
- YAML
537
+ CONTENT
542
538
 
543
539
  lookup.options[:node] = node
544
- lookup.options[:fact_file] = filename
540
+ lookup.options[:fact_file] = file_path
545
541
  lookup.options[:render_as] = :s
546
542
  allow(lookup.command_line).to receive(:args).and_return(['g'])
547
543
  expect(run_lookup(lookup)).to eql("This is G from facts in facts hash")
548
544
  end
545
+
546
+ describe 'when retrieving given facts' do
547
+ before do
548
+ lookup.options[:node] = node
549
+ allow(lookup.command_line).to receive(:args).and_return(['g'])
550
+ end
551
+
552
+ it 'loads files with yaml extension as yaml on first try' do
553
+ file_path = file_containing('facts.yaml', <<~CONTENT)
554
+ ---
555
+ cx: ' G from facts'
556
+ CONTENT
557
+ lookup.options[:fact_file] = file_path
558
+
559
+ expect(Puppet::Util::Yaml).to receive(:safe_load_file).with(file_path, []).and_call_original
560
+ run_lookup(lookup)
561
+ end
562
+
563
+ it 'loads files with yml extension as yaml on first try' do
564
+ file_path = file_containing('facts.yml', <<~CONTENT)
565
+ ---
566
+ cx: ' G from facts'
567
+ CONTENT
568
+ lookup.options[:fact_file] = file_path
569
+
570
+ expect(Puppet::Util::Yaml).to receive(:safe_load_file).with(file_path, []).and_call_original
571
+ run_lookup(lookup)
572
+ end
573
+
574
+ it 'loads files with json extension as json on first try' do
575
+ file_path = file_containing('facts.json', <<~CONTENT)
576
+ {
577
+ "cx": " G from facts"
578
+ }
579
+ CONTENT
580
+ lookup.options[:fact_file] = file_path
581
+
582
+ expect(Puppet::Util::Json).to receive(:load_file).with(file_path, {}).and_call_original
583
+ run_lookup(lookup)
584
+ end
585
+
586
+ it 'detects file format accordingly even with random file extension' do
587
+ file_path = file_containing('facts.txt', <<~CONTENT)
588
+ {
589
+ "cx": " G from facts"
590
+ }
591
+ CONTENT
592
+ lookup.options[:fact_file] = file_path
593
+
594
+ expect(Puppet::Util::Json).to receive(:load_file_if_valid).with(file_path).and_call_original
595
+ expect(Puppet::Util::Yaml).not_to receive(:safe_load_file_if_valid).with(file_path)
596
+ run_lookup(lookup)
597
+ end
598
+
599
+ it 'detects file without extension as json due to valid contents' do
600
+ file_path = file_containing('facts', <<~CONTENT)
601
+ {
602
+ "cx": " G from facts"
603
+ }
604
+ CONTENT
605
+ lookup.options[:fact_file] = file_path
606
+
607
+ expect(Puppet::Util::Json).to receive(:load_file_if_valid).with(file_path).and_call_original
608
+ expect(Puppet::Util::Yaml).not_to receive(:safe_load_file_if_valid).with(file_path)
609
+ run_lookup(lookup)
610
+ end
611
+
612
+ it 'detects file without extension as yaml due to valid contents' do
613
+ file_path = file_containing('facts', <<~CONTENT)
614
+ ---
615
+ cx: ' G from facts'
616
+ CONTENT
617
+ lookup.options[:fact_file] = file_path
618
+
619
+ expect(Puppet::Util::Json.load_file_if_valid(file_path)).to be_nil
620
+ expect(Puppet::Util::Yaml).to receive(:safe_load_file_if_valid).with(file_path).and_call_original
621
+ run_lookup(lookup)
622
+ end
623
+
624
+ it 'raises error due to invalid contents' do
625
+ file_path = file_containing('facts.yml', <<~CONTENT)
626
+ INVALID CONTENT
627
+ CONTENT
628
+ lookup.options[:fact_file] = file_path
629
+
630
+ expect {
631
+ lookup.run_command
632
+ }.to raise_error(/Incorrectly formatted data in .+ given via the --facts flag \(only accepts yaml and json files\)/)
633
+ end
634
+
635
+ it "fails when a node doesn't have facts" do
636
+ lookup.options[:node] = "bad.node"
637
+ allow(lookup.command_line).to receive(:args).and_return(['c'])
638
+
639
+ expected_error = "No facts available for target node: #{lookup.options[:node]}"
640
+ expect { lookup.run_command }.to raise_error(RuntimeError, expected_error)
641
+ end
642
+
643
+ it 'raises error due to missing trusted information facts in --facts file' do
644
+ file_path = file_containing('facts.yaml', <<~CONTENT)
645
+ ---
646
+ fqdn: some.fqdn.com
647
+ CONTENT
648
+ lookup.options[:fact_file] = file_path
649
+
650
+ expect {
651
+ lookup.run_command
652
+ }.to raise_error(/When overriding any of the hostname,domain,fqdn,clientcert facts with #{file_path} given via the --facts flag, they must all be overridden./)
653
+ end
654
+
655
+ it 'does not fail when all trusted information facts are provided via --facts file' do
656
+ file_path = file_containing('facts.yaml', <<~CONTENT)
657
+ ---
658
+ fqdn: some.fqdn.com
659
+ hostname: some.hostname
660
+ domain: some.domain
661
+ clientcert: some.clientcert
662
+ CONTENT
663
+ lookup.options[:fact_file] = file_path
664
+
665
+ expect {
666
+ lookup.run_command
667
+ }.to exit_with(0)
668
+ end
669
+ end
549
670
  end
550
671
 
551
672
  context 'using a puppet function as data provider' do
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'puppet/concurrent/thread_local_singleton'
3
+
4
+ class PuppetSpec::Singleton
5
+ extend Puppet::Concurrent::ThreadLocalSingleton
6
+ end
7
+
8
+ # Use the `equal?` matcher to ensure we get the same object
9
+ describe Puppet::Concurrent::ThreadLocalSingleton do
10
+ it 'returns the same object for a single thread' do
11
+ expect(PuppetSpec::Singleton.singleton).to equal(PuppetSpec::Singleton.singleton)
12
+ end
13
+
14
+ it 'is not inherited for a newly created thread' do
15
+ main_thread_local = PuppetSpec::Singleton.singleton
16
+ Thread.new do
17
+ expect(main_thread_local).to_not equal(PuppetSpec::Singleton.singleton)
18
+ end.join
19
+ end
20
+
21
+ it 'does not leak outside a thread' do
22
+ thread_local = nil
23
+ Thread.new do
24
+ thread_local = PuppetSpec::Singleton.singleton
25
+ end.join
26
+ expect(thread_local).to_not equal(PuppetSpec::Singleton.singleton)
27
+ end
28
+
29
+ it 'is different for each thread' do
30
+ locals = []
31
+ Thread.new do
32
+ locals << PuppetSpec::Singleton.singleton
33
+ end.join
34
+ Thread.new do
35
+ locals << PuppetSpec::Singleton.singleton
36
+ end.join
37
+ expect(locals.first).to_not equal(locals.last)
38
+ end
39
+ end
@@ -80,7 +80,7 @@ describe Puppet::FileSystem::Uniquefile do
80
80
  lock = File.join(dir, 'path', 'to', 'lock')
81
81
 
82
82
  expect {
83
- Puppet::FileSystem::Uniquefile.open_tmp(lock) { |tmp| }
83
+ Puppet::FileSystem::Uniquefile.new('foo', lock) { |tmp| }
84
84
  }.to raise_error(Errno::ENOENT, %r{No such file or directory - A directory component in .* does not exist or is a dangling symbolic link})
85
85
  end
86
86
 
@@ -102,6 +102,12 @@ describe Puppet::FileSystem::Uniquefile do
102
102
  expect(filename).to eq(temp_rune_utf8)
103
103
  end
104
104
 
105
+ it "preserves tilde characters" do
106
+ Puppet::FileSystem::Uniquefile.open_tmp('~foo') do |file|
107
+ expect(File.basename(file.path)).to start_with('~foo')
108
+ end
109
+ end
110
+
105
111
  context "Ruby 1.9.3 Tempfile tests" do
106
112
  # the remaining tests in this file are ported directly from the ruby 1.9.3 source,
107
113
  # since most of this file was ported from there
@@ -984,11 +984,12 @@ describe "Puppet::FileSystem" do
984
984
  end
985
985
 
986
986
  it 'preserves file ownership' do
987
- allow(Puppet::FileSystem).to receive(:lstat)
988
- .with(Puppet::FileSystem.pathname(dest))
989
- .and_return(double(uid: 1, gid: 2))
987
+ FileUtils.touch(dest)
988
+ allow(File).to receive(:lstat).and_call_original
989
+ allow(File).to receive(:lstat).with(Pathname.new(dest)).and_return(double(uid: 1, gid: 2, 'directory?': false))
990
990
 
991
- expect(FileUtils).to receive(:chown).with(1, 2, /#{dest}/)
991
+ allow(File).to receive(:chown).and_call_original
992
+ expect(FileUtils).to receive(:chown).with(1, 2, any_args)
992
993
 
993
994
  Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
994
995
  end
@@ -1163,4 +1164,33 @@ describe "Puppet::FileSystem" do
1163
1164
  expect(File.mtime(dest)).to be_within(1).of(tomorrow)
1164
1165
  end
1165
1166
  end
1167
+
1168
+ context '#chmod' do
1169
+ let(:dest) { tmpfile('abs_file') }
1170
+
1171
+ it "changes the mode given an absolute string" do
1172
+ Puppet::FileSystem.touch(dest)
1173
+ Puppet::FileSystem.chmod(0644, dest)
1174
+ expect(File.stat(dest).mode & 0777).to eq(0644)
1175
+ end
1176
+
1177
+ it "returns true if given an absolute pathname" do
1178
+ Puppet::FileSystem.touch(dest)
1179
+ Puppet::FileSystem.chmod(0644, Pathname.new(dest))
1180
+ expect(File.stat(dest).mode & 0777).to eq(0644)
1181
+ end
1182
+
1183
+ it "raises if the file doesn't exist" do
1184
+ klass = Puppet::Util::Platform.windows? ? Puppet::Error : Errno::ENOENT
1185
+ expect {
1186
+ Puppet::FileSystem.chmod(0644, dest)
1187
+ }.to raise_error(klass)
1188
+ end
1189
+
1190
+ it "raises ArgumentError if dest is invalid" do
1191
+ expect {
1192
+ Puppet::FileSystem.chmod(0644, nil)
1193
+ }.to raise_error(ArgumentError, /expected Pathname, got: 'NilClass'/)
1194
+ end
1195
+ end
1166
1196
  end
@@ -90,7 +90,7 @@ describe Puppet::Forge::ModuleRelease do
90
90
  "checksums": { },
91
91
  "version": "#{module_version}",
92
92
  "description": "Standard Library for Puppet Modules",
93
- "source": "git://github.com/puppetlabs/puppetlabs-stdlib.git",
93
+ "source": "https://github.com/puppetlabs/puppetlabs-stdlib",
94
94
  "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib",
95
95
  "summary": "Puppet Module Standard Library",
96
96
  "dependencies": [
@@ -204,7 +204,7 @@ describe Puppet::Forge::ModuleRelease do
204
204
  "checksums": { },
205
205
  "version": "#{module_version}",
206
206
  "description": "Standard Library for Puppet Modules",
207
- "source": "git://github.com/puppetlabs/puppetlabs-stdlib.git",
207
+ "source": "https://github.com/puppetlabs/puppetlabs-stdlib",
208
208
  "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib",
209
209
  "summary": "Puppet Module Standard Library",
210
210
  "author": "#{module_author}",
@@ -279,7 +279,7 @@ describe Puppet::Forge::ModuleRelease do
279
279
  "checksums": { },
280
280
  "version": "#{module_version}",
281
281
  "description": "Standard Library for Puppet Modules",
282
- "source": "git://github.com/puppetlabs/puppetlabs-stdlib.git",
282
+ "source": "https://github.com/puppetlabs/puppetlabs-stdlib",
283
283
  "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib",
284
284
  "summary": "Puppet Module Standard Library",
285
285
  "dependencies": [
@@ -19,16 +19,52 @@ describe "the versioncmp function" do
19
19
  let(:type_parser) { Puppet::Pops::Types::TypeParser.singleton }
20
20
 
21
21
  it 'should raise an Error if there is less than 2 arguments' do
22
- expect { versioncmp('a,b') }.to raise_error(/expects 2 arguments, got 1/)
22
+ expect { versioncmp('a,b') }.to raise_error(/expects between 2 and 3 arguments, got 1/)
23
23
  end
24
24
 
25
- it 'should raise an Error if there is more than 2 arguments' do
26
- expect { versioncmp('a,b','foo', 'bar') }.to raise_error(/expects 2 arguments, got 3/)
25
+ it 'should raise an Error if there is more than 3 arguments' do
26
+ expect { versioncmp('a,b','foo', false, 'bar') }.to raise_error(/expects between 2 and 3 arguments, got 4/)
27
27
  end
28
28
 
29
29
  it "should call Puppet::Util::Package.versioncmp (included in scope)" do
30
- expect(Puppet::Util::Package).to receive(:versioncmp).with('1.2', '1.3').and_return(-1)
30
+ expect(Puppet::Util::Package).to receive(:versioncmp).with('1.2', '1.3', false).and_return(-1)
31
31
 
32
32
  expect(versioncmp('1.2', '1.3')).to eq(-1)
33
33
  end
34
+
35
+ context "when ignore_trailing_zeroes is true" do
36
+ it "should equate versions with 2 elements and dots but with unnecessary zero" do
37
+ expect(versioncmp("10.1.0", "10.1", true)).to eq(0)
38
+ end
39
+
40
+ it "should equate versions with 1 element and dot but with unnecessary zero" do
41
+ expect(versioncmp("11.0", "11", true)).to eq(0)
42
+ end
43
+
44
+ it "should equate versions with 1 element and dot but with unnecessary zeros" do
45
+ expect(versioncmp("11.00", "11", true)).to eq(0)
46
+ end
47
+
48
+ it "should equate versions with dots and iregular zeroes" do
49
+ expect(versioncmp("11.0.00", "11", true)).to eq(0)
50
+ end
51
+
52
+ it "should equate versions with dashes" do
53
+ expect(versioncmp("10.1-0", "10.1.0-0", true)).to eq(0)
54
+ end
55
+
56
+ it "should compare versions with dashes after normalization" do
57
+ expect(versioncmp("10.1-1", "10.1.0-0", true)).to eq(1)
58
+ end
59
+
60
+ it "should not normalize versions if zeros are not trailing" do
61
+ expect(versioncmp("1.1", "1.0.1", true)).to eq(1)
62
+ end
63
+ end
64
+
65
+ context "when ignore_trailing_zeroes is false" do
66
+ it "should not equate versions if zeros are not trailing" do
67
+ expect(versioncmp("1.1", "1.0.1")).to eq(1)
68
+ end
69
+ end
34
70
  end