Skip to content

Commit 0edf99b

Browse files
authored
Merge pull request #74 from github/kpaulisse-enc-override
Enhancement: Allow override of ENC parameters
2 parents 8d22de3 + 01a74c6 commit 0edf99b

File tree

22 files changed

+631
-39
lines changed

22 files changed

+631
-39
lines changed

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.99.rc1
1+
0.99.rc2

doc/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@
77
<th>Description / Changes</th>
88
</tr>
99
</thead><tbody>
10+
<tr valign=top>
11+
<td>0.99.0rc2</td>
12+
<td>2017-01-23</td>
13+
<td>
14+
<ul>
15+
<li><a href="https://github.com/github/octocatalog-diff/pull/70">#70</a> Missing `[]=` method in display code</li>
16+
<li><a href="https://github.com/github/octocatalog-diff/pull/77">#77</a> `FactOverride` -> `Override`</li>
17+
<li><a href="https://github.com/github/octocatalog-diff/pull/74">#74</a> Allow override of ENC parameters</li>
18+
</ul>
19+
</td>
20+
</tr>
21+
1022
<tr valign=top>
1123
<td>0.99.0rc1</td>
1224
<td>2017-01-16</td>

doc/advanced-override-enc.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Overriding ENC parameters
2+
3+
One powerful feature of `octocatalog-diff` allows you to override ENC parameters when compiling the catalogs, to predict the effect of an ENC parameter change on the catalog. This is useful to simulate a change in agent node configuration without actually setting up an agent to do so.
4+
5+
## Usage
6+
7+
To override an ENC parameter in both catalogs:
8+
9+
```
10+
--enc-override parameters::some_class::some_param=value
11+
```
12+
13+
To override an ENC parameter in the "to" catalog:
14+
15+
```
16+
--to-enc-override parameters::some_class::some_param=value
17+
```
18+
19+
To override an ENC parameter in the "from" catalog:
20+
21+
```
22+
--from-enc-override parameters::some_class::some_param=value
23+
```
24+
25+
You may use as many of these arguments as you wish to adjust as many ENC parameters as you wish.
26+
27+
## Limitations
28+
29+
As presently implemented, this only works on ENCs that supply their results as YAML.
30+
31+
Is your ENC doing something different? Please [let us know](https://github.com/github/octocatalog-diff/issues/new) so we can enhance octocatalog-diff to handle it!
32+
33+
## Examples
34+
35+
Simulate a change to a top-level parameter named "role" only in the "to" catalog:
36+
37+
```
38+
octocatalog-diff -n some-node.example.com -f master -t master \
39+
--to-enc-override parameters::role=some_new_role
40+
```
41+
42+
Simulate a change in a class parameter between the catalogs:
43+
44+
```
45+
octocatalog-diff -n some-node.example.com -f master -t master \
46+
--from-enc-override parameters::my_class::my_value=value_in_old \
47+
--to-enc-override parameters::my_class::my_value=value_in_new
48+
```
49+
50+
Note that each of the examples specified the from branch and to branch to be `master`. There is no requirement that you do this, but you can generally obtain the most accurate test results by changing only one variable at a time.
51+
52+
## Advanced usage
53+
54+
The format for declaring overrides with data types is the same as [overriding facts](/doc/advanced-override-facts.md#advanced-usage).

doc/advanced.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ See also:
1818
- [Building catalogs instead of diffing catalogs](/doc/advanced-catalog-only.md)
1919
- [Enabling storeconfigs for exported resources in PuppetDB](/doc/advanced-storeconfigs.md)
2020
- [Fetching catalogs from Puppet Master / PuppetServer](/doc/advanced-puppet-master.md)
21+
- [Overriding ENC parameters](/doc/advanced-override-enc.md)
2122
- [Overriding facts](/doc/advanced-override-facts.md)
2223
- [Puppet Enterprise node classification service](/doc/advanced-pe-enc.md)
2324
- [Using `octocatalog-diff` without git](/doc/advanced-using-without-git.md)

doc/dev/api/v1/objects/fact_override.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

doc/optionsref.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ Usage: octocatalog-diff [command line options]
118118
Full path to key file for SSL client auth to Puppet Master for the to branch
119119
--from-puppet-master-ssl-client-key STRING
120120
Full path to key file for SSL client auth to Puppet Master for the from branch
121+
--enc-override STRING1[,STRING2[,...]]
122+
Override parameter from ENC globally
123+
--to-enc-override STRING1[,STRING2[,...]]
124+
Override parameter from ENC for the to branch
125+
--from-enc-override STRING1[,STRING2[,...]]
126+
Override parameter from ENC for the from branch
121127
--pe-enc-url URL Base URL for Puppet Enterprise ENC endpoint
122128
--pe-enc-token TOKEN Token to access the Puppet Enterprise ENC API
123129
--pe-enc-token-file PATH Path containing token for PE node classifier, relative or absolute

lib/octocatalog-diff/catalog-util/builddir.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ def install_directory_symlink(logger, dir, target = 'environments/production')
195195
def install_enc(logger)
196196
raise ArgumentError, 'A node must be specified when using an ENC' unless @node.is_a?(String)
197197
enc_obj = OctocatalogDiff::CatalogUtil::ENC.new(@options.merge(tempdir: @tempdir))
198+
enc_obj.execute(logger)
198199
raise "Failed ENC: #{enc_obj.error_message}" if enc_obj.error_message
199200

200201
enc_path = File.join(@tempdir, 'enc.sh')

lib/octocatalog-diff/catalog-util/enc.rb

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require_relative 'enc/script'
66

77
require 'stringio'
8+
require 'yaml'
89

910
module OctocatalogDiff
1011
module CatalogUtil
@@ -32,20 +33,64 @@ def initialize(options = {})
3233

3334
# Retrieve content
3435
# @return [String] ENC content, or nil if there was an error
35-
def content
36-
execute
36+
def content(logger = nil)
37+
execute(logger)
3738
@content ||= @enc_obj.content
3839
end
3940

4041
# Retrieve error message
4142
# @return [String] Error message, or nil if there was no error
42-
def error_message
43-
execute
43+
def error_message(logger = nil)
44+
execute(logger)
4445
@error_message ||= @enc_obj.error_message
4546
end
4647

48+
# Execute the 'execute' method of the object, but only once
49+
# @param [Logger] Logger (optional) - if not supplied any logger messages will be discarded
50+
def execute(logger = nil)
51+
return if @executed
52+
logger ||= @options[:logger]
53+
logger ||= Logger.new(StringIO.new)
54+
@enc_obj.execute(logger) if @enc_obj.respond_to?(:execute)
55+
@executed = true
56+
override_enc_parameters(logger)
57+
end
58+
4759
private
4860

61+
# Override of ENC parameters with parameters specified on the command line.
62+
# Modifies structures in @enc_obj.
63+
# @param logger [Logger] Logger object
64+
def override_enc_parameters(logger)
65+
return unless @options[:enc_override].is_a?(Array) && @options[:enc_override].any?
66+
content_structure = YAML.load(content)
67+
@options[:enc_override].each do |x|
68+
merge_enc_param(content_structure, x.key, x.value)
69+
logger.debug "ENC override: #{x.key} #{x.value.nil? ? 'DELETED' : '= ' + x.value.inspect}"
70+
end
71+
@content = content_structure.to_yaml
72+
end
73+
74+
# Merging behavior for ENC overrides
75+
# @param pointer [Hash] Portion of the content structure to modify
76+
# @param key [String] String representing structure, delimited by '::'
77+
# @param value [?] Value to insert at structure point
78+
def merge_enc_param(pointer, key, value)
79+
if key =~ /::/
80+
first_key, the_rest = key.split(/::/, 2)
81+
if pointer[first_key].nil?
82+
pointer[first_key] = {}
83+
elsif !pointer[first_key].is_a?(Hash)
84+
raise ArgumentError, "Attempt to override #{pointer[first_key].class} with hash for #{key}"
85+
end
86+
merge_enc_param(pointer[first_key], the_rest, value)
87+
elsif value.nil?
88+
pointer.delete(key)
89+
else
90+
pointer[key] = value
91+
end
92+
end
93+
4994
# Backend - given options, choose an appropriate backend and construct the corresponding object.
5095
# @return [?] Backend object
5196
def backend
@@ -64,16 +109,6 @@ def backend
64109
# At this point we do not know what backend to use for the ENC
65110
raise ArgumentError, 'Unable to determine ENC backend to use'
66111
end
67-
68-
# Execute the 'execute' method of the object, but only once
69-
# @param [Logger] Logger (optional) - if not supplied any logger messages will be discarded
70-
def execute(logger = nil)
71-
return if @executed
72-
logger ||= @options[:logger]
73-
logger ||= Logger.new(StringIO.new)
74-
@enc_obj.execute(logger) if @enc_obj.respond_to?(:execute)
75-
@executed = true
76-
end
77112
end
78113
end
79114
end

lib/octocatalog-diff/cli.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ def self.cli(argv = ARGV, logger = Logger.new(STDERR), opts = {})
8181
veto_with_none_options = %w(hiera_path hiera_path_strip)
8282
veto_with_none_options.each { |x| options.delete(x.to_sym) if options[x.to_sym] == :none }
8383

84+
# Fact and ENC overrides come in here - 'options' is modified
8485
setup_fact_overrides(options)
86+
setup_enc_overrides(options)
8587

8688
# Configure the logger and logger.debug initial information
8789
# 'logger' is modified and used
@@ -142,6 +144,12 @@ def self.setup_fact_overrides(options)
142144
setup_overrides(:to_fact_override, options)
143145
end
144146

147+
# ENC parameter overrides come in here
148+
def self.setup_enc_overrides(options)
149+
setup_overrides(:from_enc_override, options)
150+
setup_overrides(:to_enc_override, options)
151+
end
152+
145153
# Helper method: Configure and setup logger
146154
def self.setup_logger(logger, options, argv_save)
147155
# Configure the logger
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
# Allow override of ENC parameters on the command line. ENC parameter overrides can be supplied for the 'to' or 'from' catalog,
4+
# or for both. There is some attempt to handle data types here (since all items on the command line are strings)
5+
# by permitting a data type specification as well. For parameters nested in hashes, use `::` as the delimiter.
6+
OctocatalogDiff::Cli::Options::Option.newoption(:enc_override) do
7+
has_weight 322
8+
9+
def parse(parser, options)
10+
# Set 'enc_override_in' because more processing is needed, once the command line options
11+
# have been parsed, to make this into the final form 'enc_override'.
12+
OctocatalogDiff::Cli::Options.option_globally_or_per_branch(
13+
parser: parser,
14+
options: options,
15+
cli_name: 'enc-override',
16+
option_name: 'enc_override_in',
17+
desc: 'Override parameter from ENC',
18+
datatype: []
19+
)
20+
end
21+
end

0 commit comments

Comments
 (0)