puppet 4.10.6-universal-darwin → 4.10.7-universal-darwin

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.

@@ -65,50 +65,54 @@ puppet-device(8) -- Manage remote network devices
65
65
 
66
66
  SYNOPSIS
67
67
  --------
68
- Retrieves all configurations from the puppet master and apply
69
- them to the remote devices configured in /etc/puppetlabs/puppet/device.conf.
68
+ Retrieves catalogs from the Puppet master and applies them to remote devices.
69
+
70
+ This subcommand can be run manually; or periodically using cron,
71
+ a scheduled task, or a similar tool.
70
72
 
71
- Currently must be run out periodically, using cron or something similar.
72
73
 
73
74
  USAGE
74
75
  -----
75
- puppet device [-d|--debug] [--detailed-exitcodes] [-V|--version]
76
+ puppet device [-d|--debug] [--detailed-exitcodes]
76
77
  [-h|--help] [-l|--logdest syslog|<file>|console]
77
78
  [-v|--verbose] [-w|--waitforcert <seconds>]
79
+ [--user=<user>] [-V|--version]
78
80
 
79
81
 
80
82
  DESCRIPTION
81
83
  -----------
82
- Once the client has a signed certificate for a given remote device, it will
83
- retrieve its configuration and apply it.
84
+ Devices require a proxy Puppet agent to request certificates, collect facts,
85
+ retrieve and apply catalogs, and store reports.
86
+
84
87
 
85
88
  USAGE NOTES
86
89
  -----------
87
- One need a /etc/puppetlabs/puppet/device.conf file with the following content:
90
+ Devices managed by the puppet-device subcommand on a Puppet agent are
91
+ configured in device.conf, which is located at $confdir/device.conf by default,
92
+ and is configurable with the $deviceconfig setting.
93
+
94
+ The device.conf file is an INI-like file, with one section per device:
95
+
96
+ [<DEVICE_CERTNAME>]
97
+ type <TYPE>
98
+ url <URL>
99
+ debug
88
100
 
89
- [remote.device.fqdn]
90
- type <type>
91
- url <url>
101
+ The section name specifies the certname of the device.
92
102
 
93
- where:
94
- * type: the current device type (the only value at this time is cisco)
95
- * url: an url allowing to connect to the device
103
+ The values for the type and url properties are specific to each type of device.
96
104
 
97
- Supported url must conforms to:
98
- scheme://user:password@hostname/?query
105
+ The optional debug property specifies transport-level debugging,
106
+ and is limited to telnet and ssh transports.
107
+
108
+ See https://docs.puppet.com/puppet/latest/config_file_device.html for details.
99
109
 
100
- with:
101
- * scheme: either ssh or telnet
102
- * user: username, can be omitted depending on the switch/router configuration
103
- * password: the connection password
104
- * query: this is device specific. Cisco devices supports an enable parameter whose
105
- value would be the enable password.
106
110
 
107
111
  OPTIONS
108
112
  -------
109
- Note that any setting that's valid in the configuration file
110
- is also a valid long argument. For example, 'server' is a valid configuration
111
- parameter, so you can specify '--server <servername>' as an argument.
113
+ Note that any setting that's valid in the configuration file is also a valid
114
+ long argument. For example, 'server' is a valid configuration parameter, so
115
+ you can specify '--server <servername>' as an argument.
112
116
 
113
117
  * --debug:
114
118
  Enable full debugging.
@@ -133,6 +137,10 @@ parameter, so you can specify '--server <servername>' as an argument.
133
137
  appending nature of logging. It must be appended manually to make the content
134
138
  valid JSON.
135
139
 
140
+ * --user:
141
+ The user to run as. '--user=root' is required, even when run as root,
142
+ for runs that create device certificates or keys.
143
+
136
144
  * --verbose:
137
145
  Turn on verbose reporting.
138
146
 
@@ -141,8 +149,8 @@ parameter, so you can specify '--server <servername>' as an argument.
141
149
  and it is enabled by default, with a value of 120 (seconds). This causes
142
150
  +puppet agent+ to connect to the server every 2 minutes and ask it to sign a
143
151
  certificate request. This is useful for the initial setup of a puppet
144
- client. You can turn off waiting for certificates by specifying a time
145
- of 0.
152
+ client. You can turn off waiting for certificates by specifying a time of 0.
153
+
146
154
 
147
155
  EXAMPLE
148
156
  -------
@@ -21,6 +21,9 @@
21
21
  # `epp('apache/vhost/_docroot.epp', { 'docroot' => '/var/www/html',
22
22
  # 'virtual_docroot' => '/var/www/example' })`
23
23
  #
24
+ # This function can also accept an absolute path, which can load a template file
25
+ # from anywhere on disk.
26
+ #
24
27
  # Puppet produces a syntax error if you pass more parameters than are declared in
25
28
  # the template's parameter tag. When passing parameters to a template that
26
29
  # contains a parameter tag, use the same names as the tag's declared parameters.
@@ -40,7 +40,7 @@ module Puppet
40
40
  values = property.value_collection.instance_variable_get('@values') || {}
41
41
  values.each do |_, value|
42
42
  if value.regex?
43
- regexes << "/#{value.name.source.gsub(/\//, '\/')}/"
43
+ regexes << Puppet::Pops::Types::StringConverter.convert(value.name, '%p')
44
44
  next
45
45
  end
46
46
 
@@ -207,7 +207,7 @@ class Puppet::Indirector::Request
207
207
  if primary_server = Puppet.settings[:server_list][0]
208
208
  bound_server = primary_server[0]
209
209
  else
210
- bound_server = nil
210
+ bound_server = Puppet.settings[:server]
211
211
  end
212
212
  end
213
213
 
@@ -217,11 +217,11 @@ class Puppet::Indirector::Request
217
217
  if primary_server = Puppet.settings[:server_list][0]
218
218
  bound_port = primary_server[1]
219
219
  else
220
- bound_port = nil
220
+ bound_port = Puppet.settings[:masterport]
221
221
  end
222
222
  end
223
- self.server = default_server || bound_server || Puppet.settings[:server]
224
- self.port = default_port || bound_port || Puppet.settings[:masterport]
223
+ self.server = default_server || bound_server
224
+ self.port = default_port || bound_port
225
225
 
226
226
  Puppet.debug "No more servers left, falling back to #{self.server}:#{self.port}" if Puppet.settings[:use_srv_records]
227
227
 
@@ -70,6 +70,6 @@ class Puppet::Parser::AST::Regex < Puppet::Parser::AST::Leaf
70
70
  end
71
71
 
72
72
  def to_s
73
- "/#{@value.source}/"
73
+ Puppet::Pops::Types::PRegexpType.regexp_to_s_with_delimiters(@value)
74
74
  end
75
75
  end
@@ -22,6 +22,9 @@ function like this:
22
22
  `epp('apache/vhost/_docroot.epp', { 'docroot' => '/var/www/html',
23
23
  'virtual_docroot' => '/var/www/example' })`
24
24
 
25
+ This function can also accept an absolute path, which can load a template file
26
+ from anywhere on disk.
27
+
25
28
  Puppet produces a syntax error if you pass more parameters than are declared in
26
29
  the template's parameter tag. When passing parameters to a template that
27
30
  contains a parameter tag, use the same names as the tag's declared parameters.
@@ -1087,7 +1087,7 @@ class EvaluatorImpl
1087
1087
  end
1088
1088
 
1089
1089
  def string_Regexp(o, scope)
1090
- "/#{o.source}/"
1090
+ Types::PRegexpType.regexp_to_s_with_delimiters(o)
1091
1091
  end
1092
1092
 
1093
1093
  def string_PAnyType(o, scope)
@@ -159,7 +159,7 @@ class Puppet::Pops::Model::ModelTreeDumper < Puppet::Pops::Model::TreeDumper
159
159
  end
160
160
 
161
161
  def dump_LiteralRegularExpression o
162
- "/#{o.value.source}/"
162
+ Puppet::Pops::Types::StringConverter.convert(o.value, '%p')
163
163
  end
164
164
 
165
165
  def dump_Nop o
@@ -48,7 +48,7 @@ module Puppet::Pops::Patterns
48
48
 
49
49
  # VAR_NAME matches the name part of a variable (The $ character is not included)
50
50
  # Note, that only the final segment may start with an underscore.
51
- VAR_NAME = %r{\A(?:(::)?[a-z]\w*)*(?:(::)?[a-z_]\w*)\z}
51
+ VAR_NAME = %r{\A(?:((::)?[a-z]\w*)*(?:(::)?_\w*)?)\z}
52
52
 
53
53
  # PARAM_NAME matches the name part of a parameter (The $ character is not included)
54
54
  PARAM_NAME = %r{\A[a-z_]\w*\z}
@@ -826,12 +826,10 @@ class StringConverter
826
826
  f = get_format(val_type, format_map)
827
827
  case f.format
828
828
  when :p
829
- rx_s = val.options == 0 ? val.source : val.to_s
830
- rx_s = rx_s.gsub(/\//, '\/') unless Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
831
- str_regexp = "/#{rx_s}/"
829
+ str_regexp = PRegexpType.regexp_to_s_with_delimiters(val)
832
830
  f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.gsub('p', 's'), str_regexp)
833
831
  when :s
834
- str_regexp = val.options == 0 ? val.source : val.to_s
832
+ str_regexp = PRegexpType.regexp_to_s(val)
835
833
  str_regexp = puppet_quote(str_regexp) if f.alt?
836
834
  f.orig_fmt == '%s' ? str_regexp : Kernel.format(f.orig_fmt, str_regexp)
837
835
  else
@@ -606,7 +606,7 @@ class TypeCalculator
606
606
 
607
607
  # @api private
608
608
  def infer_Regexp(o)
609
- PRegexpType.new(o.source)
609
+ PRegexpType.new(o)
610
610
  end
611
611
 
612
612
  # @api private
@@ -507,7 +507,7 @@ class TypeFormatter
507
507
  def string_Numeric(t) ; @bld << t.to_s ; end
508
508
 
509
509
  # @api private
510
- def string_Regexp(t) ; @bld << t.inspect; end
510
+ def string_Regexp(t) ; @bld << PRegexpType.regexp_to_s_with_delimiters(t); end
511
511
 
512
512
  # @api private
513
513
  def string_String(t)
@@ -1573,10 +1573,64 @@ class PRegexpType < PScalarType
1573
1573
 
1574
1574
  attr_reader :pattern
1575
1575
 
1576
+ # @param regexp [Regexp] the regular expression
1577
+ # @return [String] the Regexp as a slash delimited string with slashes escaped
1578
+ def self.regexp_to_s_with_delimiters(regexp)
1579
+ regexp.options == 0 ? regexp.inspect : "/#{regexp.to_s}/"
1580
+ end
1581
+
1582
+ # @param regexp [Regexp] the regular expression
1583
+ # @return [String] the Regexp as a string without escaped slash
1584
+ def self.regexp_to_s(regexp)
1585
+ # Rubies < 2.0.0 retains escaped delimiters in the source string.
1586
+ @source_retains_escaped_slash ||= Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
1587
+ source = regexp.source
1588
+ if @source_retains_escaped_slash && source.include?('\\')
1589
+ # Restore corrupt string in rubies <2.0.0, i.e. turn '\/' into '/' but
1590
+ # don't touch valid escapes such as '\s', '\{' etc.
1591
+ escaped = false
1592
+ bld = ''
1593
+ source.each_codepoint do |codepoint|
1594
+ if escaped
1595
+ bld << 0x5c unless codepoint == 0x2f # '/'
1596
+ bld << codepoint
1597
+ escaped = false
1598
+ elsif codepoint == 0x5c # '\'
1599
+ escaped = true
1600
+ elsif codepoint <= 0x7f
1601
+ bld << codepoint
1602
+ else
1603
+ bld << [codepoint].pack('U')
1604
+ end
1605
+ end
1606
+ source = bld
1607
+ end
1608
+ append_flags_group(source, regexp.options)
1609
+ end
1610
+
1611
+ def self.append_flags_group(rx_string, options)
1612
+ if options == 0
1613
+ rx_string
1614
+ else
1615
+ bld = '(?'
1616
+ bld << 'i' if (options & Regexp::IGNORECASE) != 0
1617
+ bld << 'm' if (options & Regexp::MULTILINE) != 0
1618
+ bld << 'x' if (options & Regexp::EXTENDED) != 0
1619
+ unless options == (Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED)
1620
+ bld << '-'
1621
+ bld << 'i' if (options & Regexp::IGNORECASE) == 0
1622
+ bld << 'm' if (options & Regexp::MULTILINE) == 0
1623
+ bld << 'x' if (options & Regexp::EXTENDED) == 0
1624
+ end
1625
+ bld << ':' << rx_string << ')'
1626
+ bld.freeze
1627
+ end
1628
+ end
1629
+
1576
1630
  def initialize(pattern)
1577
1631
  if pattern.is_a?(Regexp)
1578
1632
  @regexp = pattern
1579
- @pattern = pattern.options == 0 ? pattern.source : pattern.to_s
1633
+ @pattern = PRegexpType.regexp_to_s(pattern)
1580
1634
  else
1581
1635
  @pattern = pattern
1582
1636
  end
@@ -1595,7 +1649,7 @@ class PRegexpType < PScalarType
1595
1649
  end
1596
1650
 
1597
1651
  def instance?(o, guard=nil)
1598
- o.is_a?(Regexp) && (@pattern.nil? || @pattern == (o.options == 0 ? o.source : o.to_s))
1652
+ o.is_a?(Regexp) && @pattern.nil? || regexp == o
1599
1653
  end
1600
1654
 
1601
1655
  DEFAULT = PRegexpType.new(nil)
@@ -38,7 +38,7 @@ Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package d
38
38
 
39
39
  return unless packages.detect { |name, package| package.should(:ensure) == :latest }
40
40
 
41
- sources = packages.collect { |name, package| package[:source] }.uniq
41
+ sources = packages.collect { |name, package| package[:source] }.uniq.compact
42
42
 
43
43
  updates = {}
44
44
  sources.each do |source|
@@ -92,6 +92,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
92
92
  updates = Hash.new { |h, k| h[k] = [] }
93
93
  body.split.each_slice(3) do |tuple|
94
94
  break if tuple[0] =~ /^(Obsoleting|Security:|Update)/
95
+ break unless tuple[1].match(/^(?:(\d+):)?(\S+)-(\S+)$/)
95
96
  hash = update_to_hash(*tuple[0..1])
96
97
  # Create entries for both the package name without a version and a
97
98
  # version since yum considers those as mostly interchangeable.
@@ -53,17 +53,21 @@ module Puppet::Util::Windows::APITypes
53
53
  alias_method :read_word, :read_uint16
54
54
  alias_method :read_array_of_wchar, :read_array_of_uint16
55
55
 
56
- def read_wide_string(char_length, dst_encoding = Encoding::UTF_8)
56
+ def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, encode_options = {})
57
57
  # char_length is number of wide chars (typically excluding NULLs), *not* bytes
58
58
  str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
59
- str.encode(dst_encoding)
59
+ str.encode(dst_encoding, str.encoding, encode_options)
60
+ rescue Exception => e
61
+ Puppet.debug "Unable to convert value #{str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
62
+ raise
60
63
  end
61
64
 
62
65
  # @param max_char_length [Integer] Maximum number of wide chars to return (typically excluding NULLs), *not* bytes
63
66
  # @param null_terminator [Symbol] Number of number of null wchar characters, *not* bytes, that determine the end of the string
64
67
  # null_terminator = :single_null, then the terminating sequence is two bytes of zero. This is UNIT16 = 0
65
68
  # null_terminator = :double_null, then the terminating sequence is four bytes of zero. This is UNIT32 = 0
66
- def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null)
69
+ # @param encode_options [Hash] Accepts the same option hash that may be passed to String#encode in Ruby
70
+ def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
67
71
  if null_terminator != :single_null && null_terminator != :double_null
68
72
  raise "Unable to read wide strings with #{null_terminator} terminal nulls"
69
73
  end
@@ -73,11 +77,11 @@ module Puppet::Util::Windows::APITypes
73
77
 
74
78
  # Look for a null terminating characters; if found, read up to that null (exclusive)
75
79
  (0...max_char_length - terminator_width).each do |i|
76
- return read_wide_string(i) if send(reader_method, (i * 2)) == 0
80
+ return read_wide_string(i, Encoding::UTF_8, encode_options) if send(reader_method, (i * 2)) == 0
77
81
  end
78
82
 
79
83
  # String is longer than the max; read just to the max
80
- read_wide_string(max_char_length)
84
+ read_wide_string(max_char_length, Encoding::UTF_8, encode_options)
81
85
  end
82
86
 
83
87
  def read_win32_local_pointer(&block)
@@ -236,9 +236,17 @@ module Puppet::Util::Windows::Process
236
236
  def get_environment_strings
237
237
  env_ptr = GetEnvironmentStringsW()
238
238
 
239
- pairs = env_ptr.read_arbitrary_wide_string_up_to(65534, :double_null)
239
+ # pass :invalid => :replace to the Ruby String#encode to use replacement characters
240
+ pairs = env_ptr.read_arbitrary_wide_string_up_to(65534, :double_null, { :invalid => :replace })
240
241
  .split(?\x00)
241
242
  .reject { |env_str| env_str.nil? || env_str.empty? || env_str[0] == '=' }
243
+ .reject do |env_str|
244
+ # reject any string containing the Unicode replacement character
245
+ if env_str.include?("\uFFFD")
246
+ Puppet.warning("Discarding environment variable #{env_str} which contains invalid bytes")
247
+ true
248
+ end
249
+ end
242
250
  .map { |env_pair| env_pair.split('=', 2) }
243
251
  Hash[ pairs ]
244
252
  ensure
@@ -6,7 +6,7 @@
6
6
  # Raketasks and such to set the version based on the output of `git describe`
7
7
 
8
8
  module Puppet
9
- PUPPETVERSION = '4.10.6'
9
+ PUPPETVERSION = '4.10.7'
10
10
 
11
11
  ##
12
12
  # version is a public API method intended to always provide a fast and
@@ -0,0 +1,36 @@
1
+ Loaded plugins: fastestmirror
2
+ Loading mirror speeds from cached hostfile
3
+
4
+ NetworkManager.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
5
+ NetworkManager-glib.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
6
+ NetworkManager-tui.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
7
+ alsa-firmware.noarch 1.0.28-2.el7 base
8
+ alsa-lib.x86_64 1.0.28-2.el7 base
9
+ audit.x86_64 2.4.1-5.el7 base
10
+ audit-libs.x86_64 2.4.1-5.el7 base
11
+ authconfig.x86_64 6.2.8-9.el7 base
12
+ avahi.x86_64 0.6.31-14.el7 base
13
+ avahi-autoipd.x86_64 0.6.31-14.el7 base
14
+ avahi-libs.x86_64 0.6.31-14.el7 base
15
+ bash.x86_64 4.2.46-12.el7 base
16
+ bind-libs-lite.x86_64 32:9.9.4-18.el7_1.1 updates
17
+ bind-license.noarch 32:9.9.4-18.el7_1.1 updates
18
+ binutils.x86_64 2.23.52.0.1-30.el7_1.2 updates
19
+ biosdevname.x86_64 0.6.1-2.el7 base
20
+ btrfs-progs.x86_64 3.16.2-1.el7 base
21
+ ca-certificates.noarch 2015.2.4-70.0.el7_1 updates
22
+ centos-logos.noarch 70.0.6-2.el7.centos updates
23
+ centos-release.x86_64 7-1.1503.el7.centos.2.8 base
24
+ cpp.x86_64 4.8.3-9.el7 base
25
+ cronie.x86_64 1.4.11-13.el7 base
26
+ cronie-anacron.x86_64 1.4.11-13.el7 base
27
+ cryptsetup-libs.x86_64 1.6.6-3.el7 base
28
+ dbus.x86_64 1:1.6.12-11.el7 base
29
+ dbus-libs.x86_64 1:1.6.12-11.el7 base
30
+ device-mapper.x86_64 7:1.02.93-3.el7 base
31
+ device-mapper-event.x86_64 7:1.02.93-3.el7 base
32
+ device-mapper-event-libs.x86_64 7:1.02.93-3.el7 base
33
+ device-mapper-libs.x86_64 7:1.02.93-3.el7 base
34
+ Random plugin output
35
+ Loaded plugins: fastestmirror, product-id, fake-plugin
36
+ Random plugin failed, is the mirror available?
@@ -34,6 +34,51 @@ describe "Puppet::Util::Windows::Process", :if => Puppet.features.microsoft_wind
34
34
  end
35
35
  end
36
36
 
37
+ describe "when reading environment variables" do
38
+ after :each do
39
+ # spec\integration\test\test_helper_spec.rb calls set_environment_strings
40
+ # after :all and thus needs access to the real APIs once again
41
+ Puppet::Util::Windows::Process.unstub(:GetEnvironmentStringsW)
42
+ Puppet::Util::Windows::Process.unstub(:FreeEnvironmentStringsW)
43
+ end
44
+
45
+ it "will ignore only keys or values with corrupt byte sequences" do
46
+ arraydest = []
47
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest))
48
+
49
+ env_vars = {}
50
+
51
+ # Create a UTF-16LE version of the below null separated environment string
52
+ # "a=b\x00c=d\x00e=\xDD\xDD\x00f=g\x00\x00"
53
+ env_var_block =
54
+ "a=b\x00".encode(Encoding::UTF_16LE) +
55
+ "c=d\x00".encode(Encoding::UTF_16LE) +
56
+ 'e='.encode(Encoding::UTF_16LE) + "\xDD\xDD".force_encoding(Encoding::UTF_16LE) + "\x00".encode(Encoding::UTF_16LE) +
57
+ "f=g\x00\x00".encode(Encoding::UTF_16LE)
58
+
59
+ env_var_block_bytes = env_var_block.bytes.to_a
60
+
61
+ FFI::MemoryPointer.new(:byte, env_var_block_bytes.count) do |ptr|
62
+ # uchar here is synonymous with byte
63
+ ptr.put_array_of_uchar(0, env_var_block_bytes)
64
+
65
+ # stub the block of memory that the Win32 API would typically return via pointer
66
+ Puppet::Util::Windows::Process.expects(:GetEnvironmentStringsW).returns(ptr)
67
+ # stub out the real API call to free memory, else process crashes
68
+ Puppet::Util::Windows::Process.expects(:FreeEnvironmentStringsW)
69
+
70
+ env_vars = Puppet::Util::Windows::Process.get_environment_strings
71
+ end
72
+
73
+ # based on corrupted memory, the e=\xDD\xDD should have been removed from the set
74
+ expect(env_vars).to eq({'a' => 'b', 'c' => 'd', 'f' => 'g'})
75
+
76
+ # and Puppet should emit a warning about it
77
+ expect(arraydest.last.level).to eq(:warning)
78
+ expect(arraydest.last.message).to eq("Discarding environment variable e=\uFFFD which contains invalid bytes")
79
+ end
80
+ end
81
+
37
82
  describe "when setting environment variables" do
38
83
  it "can properly handle env var values with = in them" do
39
84
  begin