Skip to content

Commit a4f7b42

Browse files
authored
Merge pull request #172 from github/kpaulisse-release-branch
Release version 1.5.2
2 parents 4cb164a + d6e1349 commit a4f7b42

20 files changed

+639
-6
lines changed

.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.5.1
1+
1.5.2

doc/CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
</tr>
99
</thead><tbody>
1010

11+
<tr valign=top>
12+
<td>1.5.2</td>
13+
<td>2017-12-19</td>
14+
<td>
15+
<li><a href="https://github.com/github/octocatalog-diff/pull/169">#169</a>: (Enhancement) Puppet Enterprise RBAC token to authenticate to PuppetDB</li>
16+
<li><a href="https://github.com/github/octocatalog-diff/pull/170">#170</a>: (Enhancement) Filter to treat an object the same as a single array containing that object</li>
17+
<li><a href="https://github.com/github/octocatalog-diff/pull/165">#165</a>: (Bug Fix) Override of fact file via CLI now has precedence over value set in configuration file</li>
18+
</td>
19+
</tr>
20+
1121
<tr valign=top>
1222
<td>1.5.1</td>
1323
<td>2017-11-16</td>

doc/advanced-filter.md

+23
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Here is the list of available filters and an explanation of each:
1111

1212
- [Absent File](/doc/advanced-filter.md#absent-file) - Ignore parameter changes of a file that is declared to be absent
1313
- [JSON](/doc/advanced-filter.md#json) - Ignore whitespace differences if JSON parses to the same object
14+
- [SingleItemArray](/doc/advanced-filter.md#SingleItemArray) - Ignore differences between object and array containing only that object
1415
- [YAML](/doc/advanced-filter.md#yaml) - Ignore whitespace/comment differences if YAML parses to the same object
1516

1617
## Absent File
@@ -84,6 +85,28 @@ If a file resource has extension `.json` and a difference in its content is obse
8485

8586
This allows you to ignore changes in whitespace, comments, etc., that are not meaningful to a machine parsing the file. Note that changes to files may still trigger Puppet to restart services even though these changes are not displayed in the octocatalog-diff output.
8687

88+
## Single Item Array
89+
90+
#### Usage
91+
92+
```
93+
--filters SingleItemArray
94+
```
95+
96+
#### Description
97+
98+
When enabling the future parser or upgrading between certain versions of Puppet, the internal structure of the catalog for certain parameters can change as shown in the following example:
99+
100+
```
101+
Old: { "notify": "Service[foo]" }
102+
New: { "notify": [ "Service[foo]" ] }
103+
```
104+
105+
This filter will suppress differences for the value of a parameter when:
106+
107+
- The value in one catalog is an object, AND
108+
- The value in the other catalog is an array containing *only* that same object
109+
87110
## YAML
88111

89112
#### Usage

doc/configuration-puppetdb.md

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ The following settings can be used in a [configuration file](/doc/configuration.
3636
| `settings[:puppetdb_ssl_client_key]` | TEXT of the private key of the client SSL keypair used to authenticate to PuppetDB. Note: This variable is not set to a file path, which means you will likely want to use means you will likely want to use `File.read(...)` if you are configuring this to be read from a file. |
3737
| `settings[:puppetdb_ssl_client_pem]` | Concatenation of the text of `puppetdb_ssl_client_key` and `puppetdb_ssl_client_cert` as previously described. This is a good alternative if your certificate chain is complex and it's easier just to put everything in a single place. Note: this option is second in precedence; if `settings[:puppetdb_ssl_client_cert]` and `settings[:puppetdb_ssl_client_key]` are both set, this will be ignored. |
3838
| `settings[:puppetdb_ssl_client_password]` | Plain text string containing the password to unlock the private key. For keys generated by the Puppet Master CA, this is not required and should be left undefined. |
39+
| `settings[:puppetdb_token]` | TEXT containing the PE RBAC token used to authenticate to PuppetDB. Note: This variable is not set to a file path, which means you will likely want to use `File.read(...)` if you are configuring this to be read from a file. |
3940

4041
## Supplying necessary information via the command line
4142

@@ -48,6 +49,8 @@ The following arguments can be used on the command line.
4849
| --puppetdb-ssl-client-cert FILENAME | Path to the certificate of the client SSL keypair. |
4950
| --puppetdb-ssl-client-key FILENAME | Path to the private key of the client SSL keypair. |
5051
| --puppetdb-ssl-client-password PASSWORD_STRING | Plain text string containing the password to unlock the private key. For keys generated by the Puppet Master CA, this is not required. |
52+
| --puppetdb-token STRING | String containing the PE RBAC token used to authenticate to PuppetDB. |
53+
| --puppetdb-token-file FILENAME | Path to the PE RBAC token file used to authenticate to PuppetDB. |
5154

5255
## Supplying necessary information via the environment
5356

doc/optionsref.md

+32
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ Usage: octocatalog-diff [command line options]
8787
--to-puppet-binary STRING Full path to puppet binary for the to branch
8888
--from-puppet-binary STRING Full path to puppet binary for the from branch
8989
--facts-terminus STRING Facts terminus: one of yaml, facter
90+
--puppetdb-token TOKEN Token to access the PuppetDB API
91+
--puppetdb-token-file PATH Path containing token for PuppetDB API, relative or absolute
9092
--puppetdb-url URL PuppetDB base URL
9193
--puppetdb-ssl-ca FILENAME CA certificate that signed the PuppetDB certificate
9294
--puppetdb-ssl-client-cert FILENAME
@@ -1374,6 +1376,36 @@ the text of the password won't appear in the process list. (<a href="../lib/octo
13741376
</td>
13751377
</tr>
13761378

1379+
<tr>
1380+
<td valign=top>
1381+
<pre><code>--puppetdb-token TOKEN</code></pre>
1382+
</td>
1383+
<td valign=top>
1384+
Token to access the PuppetDB API
1385+
</td>
1386+
<td valign=top>
1387+
Specify the PE RBAC token to access the PuppetDB API. Refer to
1388+
https://puppet.com/docs/pe/latest/rbac/rbac_token_auth_intro.html#generate-a-token-using-puppet-access
1389+
for details on generating and obtaining a token. Use this option to specify the text
1390+
of the token. (Use --puppetdb-token-file to read the content of the token from a file.) (<a href="../lib/octocatalog-diff/cli/options/puppetdb_token.rb">puppetdb_token.rb</a>)
1391+
</td>
1392+
</tr>
1393+
1394+
<tr>
1395+
<td valign=top>
1396+
<pre><code>--puppetdb-token-file PATH</code></pre>
1397+
</td>
1398+
<td valign=top>
1399+
Path containing token for PuppetDB API, relative or absolute
1400+
</td>
1401+
<td valign=top>
1402+
Specify the PE RBAC token to access the PuppetDB API. Refer to
1403+
https://puppet.com/docs/pe/latest/rbac/rbac_token_auth_intro.html#generate-a-token-using-puppet-access
1404+
for details on generating and obtaining a token. Use this option to specify the text
1405+
in a file, to read the content of the token from the file. (<a href="../lib/octocatalog-diff/cli/options/puppetdb_token_file.rb">puppetdb_token_file.rb</a>)
1406+
</td>
1407+
</tr>
1408+
13771409
<tr>
13781410
<td valign=top>
13791411
<pre><code>--puppetdb-url URL</code></pre>

lib/octocatalog-diff/catalog-diff/filter.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require_relative 'filter/absent_file'
33
require_relative 'filter/compilation_dir'
44
require_relative 'filter/json'
5+
require_relative 'filter/single_item_array'
56
require_relative 'filter/yaml'
67

78
require 'stringio'
@@ -13,7 +14,7 @@ class Filter
1314
attr_accessor :logger
1415

1516
# List the available filters here (by class name) for use in the validator method.
16-
AVAILABLE_FILTERS = %w(AbsentFile CompilationDir JSON YAML).freeze
17+
AVAILABLE_FILTERS = %w(AbsentFile CompilationDir JSON SingleItemArray YAML).freeze
1718

1819
# Public: Determine whether a particular filter exists. This can be used to validate
1920
# a user-submitted filter.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../filter'
4+
5+
module OctocatalogDiff
6+
module CatalogDiff
7+
class Filter
8+
# Filter out changes in parameters when one catalog has a parameter that's an object and
9+
# the other catalog has that same parameter as an array containing the same object.
10+
# For example, under this filter, the following is not a change:
11+
# catalog1: notify => "Service[foo]"
12+
# catalog2: notify => ["Service[foo]"]
13+
class SingleItemArray < OctocatalogDiff::CatalogDiff::Filter
14+
# Public: Implement the filter for single-item arrays whose item exactly matches the
15+
# item that's not in an array in the other catalog.
16+
#
17+
# @param diff [OctocatalogDiff::API::V1::Diff] Difference
18+
# @param _options [Hash] Additional options (there are none for this filter)
19+
# @return [Boolean] true if this should be filtered out, false otherwise
20+
def filtered?(diff, _options = {})
21+
# Skip additions or removals - focus only on changes
22+
return false unless diff.change?
23+
old_value = diff.old_value
24+
new_value = diff.new_value
25+
26+
# Skip unless there is a single-item array under consideration
27+
return false unless
28+
(old_value.is_a?(Array) && old_value.size == 1) ||
29+
(new_value.is_a?(Array) && new_value.size == 1)
30+
31+
# Skip if both the old value and new value are arrays
32+
return false if old_value.is_a?(Array) && new_value.is_a?(Array)
33+
34+
# Do comparison
35+
if old_value.is_a?(Array)
36+
old_value.first == new_value
37+
else
38+
new_value.first == old_value
39+
end
40+
end
41+
end
42+
end
43+
end
44+
end

lib/octocatalog-diff/cli/options.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ def self.classes
2323

2424
# Define the Option class and newoption() method for use by cli/options/*.rb files
2525
class Option
26-
DEFAULT_WEIGHT = 999
2726
def self.has_weight(w) # rubocop:disable Style/PredicateName
2827
@weight = w
2928
end
@@ -38,7 +37,9 @@ def self.weight
3837
elsif @weight
3938
@weight
4039
else
41-
DEFAULT_WEIGHT
40+
# :nocov:
41+
raise ArgumentError, "Option #{name} does not have a weight specified. Add 'has_weight NNN' to control ordering."
42+
# :nocov:
4243
end
4344
end
4445

lib/octocatalog-diff/cli/options/pe_enc_token_file.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
def parse(parser, options)
1313
parser.on('--pe-enc-token-file PATH', 'Path containing token for PE node classifier, relative or absolute') do |x|
1414
proposed_token_path = x.start_with?('/') ? x : File.join(options[:basedir], x)
15-
raise Errno::ENOENT, "Provided token (#{proposed_token_path}) does not exist" unless File.file?(proposed_token_path)
15+
raise Errno::ENOENT, "Provided PE ENC token (#{proposed_token_path}) does not exist" unless File.file?(proposed_token_path)
1616
options[:pe_enc_token] = File.read(proposed_token_path)
1717
end
1818
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
# Specify the PE RBAC token to access the PuppetDB API. Refer to
4+
# https://puppet.com/docs/pe/latest/rbac/rbac_token_auth_intro.html#generate-a-token-using-puppet-access
5+
# for details on generating and obtaining a token. Use this option to specify the text
6+
# of the token. (Use --puppetdb-token-file to read the content of the token from a file.)
7+
# @param parser [OptionParser object] The OptionParser argument
8+
# @param options [Hash] Options hash being constructed; this is modified in this method.
9+
OctocatalogDiff::Cli::Options::Option.newoption(:puppetdb_token) do
10+
has_weight 310
11+
12+
def parse(parser, options)
13+
parser.on('--puppetdb-token TOKEN', 'Token to access the PuppetDB API') do |token|
14+
options[:puppetdb_token] = token
15+
end
16+
end
17+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
# Specify the PE RBAC token to access the PuppetDB API. Refer to
4+
# https://puppet.com/docs/pe/latest/rbac/rbac_token_auth_intro.html#generate-a-token-using-puppet-access
5+
# for details on generating and obtaining a token. Use this option to specify the text
6+
# in a file, to read the content of the token from the file.
7+
# @param parser [OptionParser object] The OptionParser argument
8+
# @param options [Hash] Options hash being constructed; this is modified in this method.
9+
OctocatalogDiff::Cli::Options::Option.newoption(:puppetdb_token_file) do
10+
has_weight 310
11+
12+
def parse(parser, options)
13+
parser.on('--puppetdb-token-file PATH', 'Path containing token for PuppetDB API, relative or absolute') do |x|
14+
proposed_token_path = x.start_with?('/') ? x : File.join(options[:basedir], x)
15+
unless File.file?(proposed_token_path)
16+
raise Errno::ENOENT, "Provided PuppetDB API token (#{proposed_token_path}) does not exist"
17+
end
18+
options[:puppetdb_token] = File.read(proposed_token_path)
19+
end
20+
end
21+
end

lib/octocatalog-diff/puppetdb.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class PuppetDB
4242
# @param :puppetdb_ssl_client_p12 [String] pkcs12-encoded client key and certificate
4343
# @param :puppetdb_ssl_client_password [String] Path to file containing password for SSL client key (any format)
4444
# @param :puppetdb_ssl_client_auth [Boolean] Override the client-auth that is guessed from parameters
45+
# @param :puppetdb_token [String] PE RBAC token to authenticate to PuppetDB API
4546
# @param :timeout [Integer] Connection timeout for PuppetDB (default=10)
4647
def initialize(options = {})
4748
@connections =
@@ -107,7 +108,10 @@ def _get(path)
107108
].join('')
108109

109110
begin
110-
more_options = { headers: { 'Accept' => 'application/json' }, timeout: @timeout }
111+
headers = { 'Accept' => 'application/json' }
112+
headers['X-Authentication'] = @options[:puppetdb_token] if @options[:puppetdb_token]
113+
more_options = { headers: headers, timeout: @timeout }
114+
111115
if connection[:username] || connection[:password]
112116
more_options[:basic_auth] = { username: connection[:username], password: connection[:password] }
113117
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"document_type": "Catalog",
3+
"data": {
4+
"tags": [
5+
"settings"
6+
],
7+
"name": "my.rspec.node",
8+
"version": "production",
9+
"environment": "production",
10+
"resources": [
11+
{
12+
"type": "File",
13+
"title": "/tmp/amazing",
14+
"file": "/environments/production/modules/foo/manifests/init.pp",
15+
"line": 10,
16+
"exported": false,
17+
"parameters": {
18+
"content": "This is my file.\nMy file is amazing.\n",
19+
"group": "root",
20+
"mode": "0755",
21+
"notify": "Service[foo]",
22+
"owner": "root"
23+
}
24+
},
25+
{
26+
"type": "File",
27+
"title": "/tmp/awesome",
28+
"file": "/environments/production/modules/foo/manifests/init.pp",
29+
"line": 20,
30+
"exported": false,
31+
"parameters": {
32+
"content": "This is my file.\nMy file is awesome.\n",
33+
"group": "root",
34+
"mode": "0755",
35+
"notify": [
36+
"Service[foo]",
37+
"Service[bar]"
38+
],
39+
"owner": "root",
40+
"subscribe": [
41+
"Service[baz]"
42+
]
43+
}
44+
},
45+
{
46+
"type": "File",
47+
"title": "/tmp/fizzbuzz",
48+
"file": "/environments/production/modules/foo/manifests/init.pp",
49+
"line": 30,
50+
"exported": false,
51+
"parameters": {
52+
"content": "1\n2\nfizz\n4\nbuzz\nfizz\n7\n8\nfizz\nbuzz\n",
53+
"group": "root",
54+
"mode": "0755",
55+
"owner": "root"
56+
}
57+
},
58+
{
59+
"type": "File",
60+
"title": "/tmp/foobar",
61+
"file": "/environments/production/modules/foo/manifests/init.pp",
62+
"line": 40,
63+
"exported": false,
64+
"parameters": {
65+
"content": "foo\nbar\n",
66+
"group": "root",
67+
"mode": "0755",
68+
"owner": "root",
69+
"notify": "Service[foobar]"
70+
}
71+
}
72+
],
73+
"classes": [
74+
"settings"
75+
]
76+
},
77+
"metadata": {
78+
"api_version": 1
79+
}
80+
}

0 commit comments

Comments
 (0)