puppet-lint 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/puppet-lint/lexer/token.rb +1 -1
- data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +6 -8
- data/lib/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations.rb +130 -0
- data/lib/puppet-lint/plugins/legacy_facts/legacy_facts.rb +2 -7
- data/lib/puppet-lint/plugins/top_scope_facts/top_scope_facts.rb +11 -1
- data/lib/puppet-lint/version.rb +1 -1
- data/spec/fixtures/test/reports/code_climate.json +1 -1
- data/spec/unit/puppet-lint/plugins/check_classes/parameter_order_spec.rb +67 -13
- data/spec/unit/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations_spec.rb +186 -0
- data/spec/unit/puppet-lint/plugins/legacy_facts/legacy_facts_spec.rb +8 -0
- data/spec/unit/puppet-lint/plugins/top_scope_facts/top_scope_facts_spec.rb +3 -47
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3953f32f31f48881c186abdd6a5ce57c2debaf28d24afc4b207a2a84a2065ccf
|
4
|
+
data.tar.gz: 60730e1ecb6cbf54f72f23bbb96769d181b9132a2fb756bdc858949e953d3467
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2421fd601c8e371f8bcfa8ffff3f5f9674fa1334d7ced66e1c0bd4a376c8365822f57b11a6d3ad80e134ea2b6faf6c20281e3497715b34c3c22db163e424cb2e
|
7
|
+
data.tar.gz: 5ab8e9650e45521eb84ea8c8f89d0970c90f919bd51e82dc6be73fc5a2b0944875673a16058ad0894288730358772ef82f07540a8ac0230bdb32aa5727abab46
|
@@ -30,7 +30,7 @@ class PuppetLint::Lexer
|
|
30
30
|
# etc) in the manifest.
|
31
31
|
attr_accessor :next_code_token
|
32
32
|
|
33
|
-
# Public: Gets/sets the previous code
|
33
|
+
# Public: Gets/sets the previous code token (skips whitespace,
|
34
34
|
# comments, etc) in the manifest.
|
35
35
|
attr_accessor :prev_code_token
|
36
36
|
|
@@ -37,7 +37,7 @@ PuppetLint.new_check(:parameter_order) do
|
|
37
37
|
column: token.column,
|
38
38
|
description: 'Test the manifest tokens for any parameterised classes or defined types that take ' \
|
39
39
|
'parameters and record a warning if there are any optional parameters listed before required parameters.',
|
40
|
-
help_uri: 'https://puppet.com/docs/puppet/latest/style_guide.html#display-order
|
40
|
+
help_uri: 'https://puppet.com/docs/puppet/latest/style_guide.html#params-display-order',
|
41
41
|
)
|
42
42
|
end
|
43
43
|
end
|
@@ -48,17 +48,15 @@ PuppetLint.new_check(:parameter_order) do
|
|
48
48
|
return false unless token.prev_code_token
|
49
49
|
|
50
50
|
[
|
51
|
-
:LPAREN,
|
52
|
-
:COMMA,
|
53
|
-
:TYPE,
|
54
|
-
:RBRACK,
|
51
|
+
:LPAREN, # First parameter, no type specification
|
52
|
+
:COMMA, # Subsequent parameter, no type specification
|
53
|
+
:TYPE, # Parameter with simple type specification
|
54
|
+
:RBRACK, # Parameter with complex type specification
|
55
|
+
:CLASSREF, # Parameter with custom type specification
|
55
56
|
].include?(token.prev_code_token.type)
|
56
57
|
end
|
57
58
|
|
58
59
|
def required_parameter?(token)
|
59
|
-
data_type = token.prev_token_of(:TYPE, skip_blocks: true)
|
60
|
-
return false if data_type && data_type.value == 'Optional'
|
61
|
-
|
62
60
|
return !(token.prev_code_token && token.prev_code_token.type == :EQUALS) if token.next_code_token.nil? || [:COMMA, :RPAREN].include?(token.next_code_token.type)
|
63
61
|
|
64
62
|
false
|
@@ -0,0 +1,130 @@
|
|
1
|
+
COMMANDS = Array['command', 'onlyif', 'unless']
|
2
|
+
INTERPOLATED_STRINGS = Array[:DQPRE, :DQMID]
|
3
|
+
USELESS_CHARS = Array[:WHITESPACE, :COMMA]
|
4
|
+
|
5
|
+
PuppetLint.new_check(:check_unsafe_interpolations) do
|
6
|
+
def check
|
7
|
+
# Gather any exec commands' resources into an array
|
8
|
+
exec_resources = resource_indexes.filter_map do |resource|
|
9
|
+
resource_parameters = resource[:param_tokens].map(&:value)
|
10
|
+
resource if resource[:type].value == 'exec' && !(COMMANDS & resource_parameters).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
# Iterate over title tokens and raise a warning if any are variables
|
14
|
+
unless get_exec_titles.empty?
|
15
|
+
get_exec_titles.each do |title|
|
16
|
+
check_unsafe_title(title)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Iterate over each command found in any exec
|
21
|
+
exec_resources.each do |command_resources|
|
22
|
+
check_unsafe_interpolations(command_resources)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Iterate over the tokens in a title and raise a warning if an interpolated variable is found
|
27
|
+
def check_unsafe_title(title)
|
28
|
+
title.each do |token|
|
29
|
+
notify_warning(token.next_code_token) if interpolated?(token)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Iterates over an exec resource and if a command, onlyif or unless paramter is found, it is checked for unsafe interpolations
|
34
|
+
def check_unsafe_interpolations(command_resources)
|
35
|
+
command_resources[:tokens].each do |token|
|
36
|
+
# Skip iteration if token isn't a command of type :NAME
|
37
|
+
next unless COMMANDS.include?(token.value) && token.type == :NAME
|
38
|
+
# Don't check the command if it is parameterised
|
39
|
+
next if parameterised?(token)
|
40
|
+
|
41
|
+
check_command(token).each do |t|
|
42
|
+
notify_warning(t)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Raises a warning given a token and message
|
48
|
+
def notify_warning(token)
|
49
|
+
notify :warning,
|
50
|
+
message: "unsafe interpolation of variable '#{token.value}' in exec command",
|
51
|
+
line: token.line,
|
52
|
+
column: token.column
|
53
|
+
end
|
54
|
+
|
55
|
+
# Iterates over the tokens in a command and adds it to an array of violations if it is an input variable
|
56
|
+
def check_command(token)
|
57
|
+
# Initialise variables needed in while loop
|
58
|
+
rule_violations = []
|
59
|
+
current_token = token
|
60
|
+
|
61
|
+
# Iterate through tokens in command
|
62
|
+
while current_token.type != :NEWLINE
|
63
|
+
# Check if token is a varibale and if it is parameterised
|
64
|
+
rule_violations.append(current_token.next_code_token) if interpolated?(current_token)
|
65
|
+
current_token = current_token.next_token
|
66
|
+
end
|
67
|
+
|
68
|
+
rule_violations
|
69
|
+
end
|
70
|
+
|
71
|
+
# A command is parameterised if its args are placed in an array
|
72
|
+
# This function checks if the current token is a :FARROW and if so, if it is followed by an LBRACK
|
73
|
+
def parameterised?(token)
|
74
|
+
current_token = token
|
75
|
+
while current_token.type != :NEWLINE
|
76
|
+
return true if current_token.type == :FARROW && current_token.next_token.next_token.type == :LBRACK
|
77
|
+
|
78
|
+
current_token = current_token.next_token
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
|
83
|
+
# This function adds a check for titles in double quotes where there could be interpolated variables
|
84
|
+
def get_exec_titles
|
85
|
+
result = []
|
86
|
+
tokens.each_with_index do |_token, token_idx|
|
87
|
+
next if tokens[token_idx].value != 'exec'
|
88
|
+
|
89
|
+
# We have a resource declaration. Now find the title
|
90
|
+
tokens_array = []
|
91
|
+
# Check if title is an array
|
92
|
+
if tokens[token_idx]&.next_code_token&.next_code_token&.type == :LBRACK
|
93
|
+
# Get the start and end indices of the array of titles
|
94
|
+
array_start_idx = tokens.rindex { |r| r.type == :LBRACK }
|
95
|
+
array_end_idx = tokens.rindex { |r| r.type == :RBRACK }
|
96
|
+
|
97
|
+
# Grab everything within the array
|
98
|
+
title_array_tokens = tokens[(array_start_idx + 1)..(array_end_idx - 1)]
|
99
|
+
tokens_array.concat(title_array_tokens.reject do |token|
|
100
|
+
USELESS_CHARS.include?(token.type)
|
101
|
+
end)
|
102
|
+
result << tokens_array
|
103
|
+
# Check if title is double quotes string
|
104
|
+
elsif tokens[token_idx].next_code_token.next_code_token.type == :DQPRE
|
105
|
+
# Find the start and end of the title
|
106
|
+
title_start_idx = tokens.find_index(tokens[token_idx].next_code_token.next_code_token)
|
107
|
+
title_end_idx = title_start_idx + index_offset_for(':', tokens[title_start_idx..tokens.length])
|
108
|
+
|
109
|
+
result << tokens[title_start_idx..title_end_idx]
|
110
|
+
# Title is in single quotes
|
111
|
+
else
|
112
|
+
tokens_array.concat([tokens[token_idx].next_code_token.next_code_token])
|
113
|
+
|
114
|
+
result << tokens_array
|
115
|
+
end
|
116
|
+
end
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
def interpolated?(token)
|
121
|
+
INTERPOLATED_STRINGS.include?(token.type)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Finds the index offset of the next instance of `value` in `tokens_slice` from the original index
|
125
|
+
def index_offset_for(value, tokens_slice)
|
126
|
+
tokens_slice.each_with_index do |token, i|
|
127
|
+
return i if value.include?(token.value)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -115,14 +115,9 @@ PuppetLint.new_check(:legacy_facts) do
|
|
115
115
|
tokens.select { |x| LEGACY_FACTS_VAR_TYPES.include?(x.type) }.each do |token|
|
116
116
|
fact_name = ''
|
117
117
|
|
118
|
-
# This matches legacy facts defined in the fact hash that use the top scope
|
119
|
-
# fact assignment.
|
120
|
-
if token.value.start_with?('::facts[')
|
121
|
-
fact_name = token.value.match(%r{::facts\['(.*)'\]})[1]
|
122
|
-
|
123
118
|
# This matches legacy facts defined in the fact hash.
|
124
|
-
|
125
|
-
fact_name =
|
119
|
+
if (match = (token.value.match(%r{(::)?facts\['(.*)'\]}) || token.value.match(%r{(::)?facts\[(.*)\]})))
|
120
|
+
fact_name = match[2]
|
126
121
|
|
127
122
|
# This matches using legacy facts in a the new structured fact. For
|
128
123
|
# example this would match 'uuid' in $facts['uuid'] so it can be converted
|
@@ -17,7 +17,17 @@ TOP_SCOPE_FACTS_VAR_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
|
|
17
17
|
|
18
18
|
PuppetLint.new_check(:top_scope_facts) do
|
19
19
|
def check
|
20
|
-
whitelist = ['trusted', 'facts'
|
20
|
+
whitelist = ['trusted', 'facts', 'architecture', 'augeasversion', 'bios_release_date', 'bios_vendor', 'bios_version',
|
21
|
+
'boardassettag', 'boardmanufacturer', 'boardproductname', 'boardserialnumber', 'chassisassettag', 'chassistype', 'domain',
|
22
|
+
'fqdn', 'gid', 'hardwareisa', 'hardwaremodel', 'hostname', 'id', 'ipaddress', 'ipaddress6', 'lsbdistcodename',
|
23
|
+
'lsbdistdescription', 'lsbdistid', 'lsbdistrelease', 'lsbmajdistrelease', 'lsbminordistrelease', 'lsbrelease',
|
24
|
+
'macaddress', 'macosx_buildversion', 'macosx_productname', 'macosx_productversion', 'macosx_productversion_major',
|
25
|
+
'macosx_productversion_minor', 'manufacturer', 'memoryfree', 'memorysize', 'netmask', 'netmask6', 'network', 'network6',
|
26
|
+
'operatingsystem', 'operatingsystemmajrelease', 'operatingsystemrelease', 'osfamily', 'physicalprocessorcount',
|
27
|
+
'processorcount', 'productname', 'rubyplatform', 'rubysitedir', 'rubyversion', 'selinux', 'selinux_config_mode',
|
28
|
+
'selinux_config_policy', 'selinux_current_mode', 'selinux_enforced', 'selinux_policyversion', 'serialnumber',
|
29
|
+
'swapencrypted', 'swapfree', 'swapsize', 'system32', 'uptime', 'uptime_days', 'uptime_hours', 'uptime_seconds',
|
30
|
+
'uuid', 'xendomains', 'zonename'] + (PuppetLint.configuration.top_scope_variables || [])
|
21
31
|
whitelist = whitelist.join('|')
|
22
32
|
tokens.select { |x| TOP_SCOPE_FACTS_VAR_TYPES.include?(x.type) }.each do |token|
|
23
33
|
next unless %r{^::}.match?(token.value)
|
data/lib/puppet-lint/version.rb
CHANGED
@@ -33,6 +33,6 @@
|
|
33
33
|
}
|
34
34
|
},
|
35
35
|
"fingerprint": "e34cf289e008446b633d1be7cf58120e",
|
36
|
-
"content": "Test the manifest tokens for any parameterised classes or defined types that take parameters and record a warning if there are any optional parameters listed before required parameters. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#display-order
|
36
|
+
"content": "Test the manifest tokens for any parameterised classes or defined types that take parameters and record a warning if there are any optional parameters listed before required parameters. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#params-display-order) for more information about the `parameter_order` check."
|
37
37
|
}
|
38
38
|
]
|
@@ -135,19 +135,6 @@ describe 'parameter_order' do
|
|
135
135
|
it { expect(problems).to have(0).problem }
|
136
136
|
end
|
137
137
|
|
138
|
-
context "#{type} parameter with Optional data type" do
|
139
|
-
let(:code) do
|
140
|
-
<<-END
|
141
|
-
#{type} test(
|
142
|
-
String $test = 'value',
|
143
|
-
Optional[String] $optional,
|
144
|
-
) { }
|
145
|
-
END
|
146
|
-
end
|
147
|
-
|
148
|
-
it { expect(problems).to have(0).problems }
|
149
|
-
end
|
150
|
-
|
151
138
|
context "#{type} parameter with array operation" do
|
152
139
|
let(:code) do
|
153
140
|
<<-END
|
@@ -165,5 +152,72 @@ describe 'parameter_order' do
|
|
165
152
|
|
166
153
|
it { expect(problems).to have(0).problems }
|
167
154
|
end
|
155
|
+
|
156
|
+
context "#{type} parameters of Optional type are just regular parameters" do
|
157
|
+
let(:code) do
|
158
|
+
<<-END
|
159
|
+
#{type} test (
|
160
|
+
String $param1 = '',
|
161
|
+
Optional[Boolean] $param2,
|
162
|
+
) { }
|
163
|
+
END
|
164
|
+
end
|
165
|
+
|
166
|
+
it { expect(problems).to have(1).problems }
|
167
|
+
end
|
168
|
+
|
169
|
+
[['Custom::Type1', 'Custom::Type2'], ['Custom::Type1', 'String'], ['String', 'Custom::Type2']].each_with_index do |testtypes, i| # rubocop:disable Performance/CollectionLiteralInLoop
|
170
|
+
context "#{type} parameters of custom type - no values - #{i}" do
|
171
|
+
let(:code) do
|
172
|
+
<<-END
|
173
|
+
#{type} test (
|
174
|
+
#{testtypes[0]} $param1,
|
175
|
+
#{testtypes[0]} $param2,
|
176
|
+
) { }
|
177
|
+
END
|
178
|
+
end
|
179
|
+
|
180
|
+
it { expect(problems).to have(0).problems }
|
181
|
+
end
|
182
|
+
|
183
|
+
context "#{type} parameters of custom type - two values - #{i}" do
|
184
|
+
let(:code) do
|
185
|
+
<<-END
|
186
|
+
#{type} test (
|
187
|
+
#{testtypes[0]} $param1 = 'foo',
|
188
|
+
#{testtypes[1]} $param2 = 'bar',
|
189
|
+
) { }
|
190
|
+
END
|
191
|
+
end
|
192
|
+
|
193
|
+
it { expect(problems).to have(0).problems }
|
194
|
+
end
|
195
|
+
|
196
|
+
context "#{type} parameters of custom type - one value, wrong order - #{i}" do
|
197
|
+
let(:code) do
|
198
|
+
<<-END
|
199
|
+
#{type} test (
|
200
|
+
#{testtypes[0]} $param1 = 'foo',
|
201
|
+
#{testtypes[1]} $param2,
|
202
|
+
) { }
|
203
|
+
END
|
204
|
+
end
|
205
|
+
|
206
|
+
it { expect(problems).to have(1).problems }
|
207
|
+
end
|
208
|
+
|
209
|
+
context "#{type} parameters of custom type - one value, right order - #{i}" do
|
210
|
+
let(:code) do
|
211
|
+
<<-END
|
212
|
+
#{type} test (
|
213
|
+
#{testtypes[0]} $param1,
|
214
|
+
#{testtypes[1]} $param2 = 'bar',
|
215
|
+
) { }
|
216
|
+
END
|
217
|
+
end
|
218
|
+
|
219
|
+
it { expect(problems).to have(0).problems }
|
220
|
+
end
|
221
|
+
end
|
168
222
|
end
|
169
223
|
end
|
data/spec/unit/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations_spec.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'check_unsafe_interpolations' do
|
4
|
+
let(:msg) { "unsafe interpolation of variable 'foo' in exec command" }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'exec with unsafe interpolation in command' do
|
8
|
+
let(:code) do
|
9
|
+
<<-PUPPET
|
10
|
+
class foo {
|
11
|
+
|
12
|
+
exec { 'bar':
|
13
|
+
command => "echo ${foo}",
|
14
|
+
}
|
15
|
+
|
16
|
+
}
|
17
|
+
PUPPET
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'detects an unsafe exec command argument' do
|
21
|
+
expect(problems).to have(1).problems
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'creates one warning' do
|
25
|
+
expect(problems).to contain_warning(msg)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'exec with multiple unsafe interpolations in command' do
|
30
|
+
let(:code) do
|
31
|
+
<<-PUPPET
|
32
|
+
class foo {
|
33
|
+
|
34
|
+
exec { 'bar':
|
35
|
+
command => "echo ${foo} ${bar}",
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|
39
|
+
PUPPET
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'detects multiple unsafe exec command arguments' do
|
43
|
+
expect(problems).to have(2).problems
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'creates two warnings' do
|
47
|
+
expect(problems).to contain_warning(msg)
|
48
|
+
expect(problems).to contain_warning(msg)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'code that uses title with unsafe string as command' do
|
53
|
+
let(:code) do
|
54
|
+
<<-PUPPET
|
55
|
+
class foo {
|
56
|
+
|
57
|
+
exec { "echo ${foo}": }
|
58
|
+
|
59
|
+
}
|
60
|
+
PUPPET
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'detects one problem' do
|
64
|
+
expect(problems).to have(1).problems
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'creates one warning' do
|
68
|
+
expect(problems).to contain_warning(msg)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'exec with a safe string in command' do
|
73
|
+
let(:code) do
|
74
|
+
<<-PUPPET
|
75
|
+
class foo {
|
76
|
+
|
77
|
+
exec { 'bar':
|
78
|
+
command => "echo foo",
|
79
|
+
}
|
80
|
+
|
81
|
+
}
|
82
|
+
PUPPET
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'detects zero problems' do
|
86
|
+
expect(problems).to have(0).problems
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'exec that has an array of args in command' do
|
91
|
+
let(:code) do
|
92
|
+
<<-PUPPET
|
93
|
+
class foo {
|
94
|
+
|
95
|
+
exec { 'bar':
|
96
|
+
command => ['echo', $foo],
|
97
|
+
}
|
98
|
+
}
|
99
|
+
PUPPET
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'detects zero problems' do
|
103
|
+
expect(problems).to have(0).problems
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'exec that has an array of args in command' do
|
108
|
+
let(:code) do
|
109
|
+
<<-PUPPET
|
110
|
+
class foo {
|
111
|
+
|
112
|
+
exec { ["foo", "bar", "baz"]:
|
113
|
+
command => echo qux,
|
114
|
+
}
|
115
|
+
}
|
116
|
+
PUPPET
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'detects zero problems' do
|
120
|
+
expect(problems).to have(0).problems
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'file resource' do
|
125
|
+
let(:code) do
|
126
|
+
<<-PUPPET
|
127
|
+
class foo {
|
128
|
+
file { '/etc/bar':
|
129
|
+
ensure => file,
|
130
|
+
backup => false,
|
131
|
+
content => $baz,
|
132
|
+
}
|
133
|
+
}
|
134
|
+
PUPPET
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'detects zero problems' do
|
138
|
+
expect(problems).to have(0).problems
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'file resource and an exec with unsafe interpolation in command' do
|
143
|
+
let(:code) do
|
144
|
+
<<-PUPPET
|
145
|
+
class foo {
|
146
|
+
file { '/etc/bar':
|
147
|
+
ensure => file,
|
148
|
+
backup => false,
|
149
|
+
content => $baz,
|
150
|
+
}
|
151
|
+
|
152
|
+
exec { 'qux':
|
153
|
+
command => "echo ${foo}",
|
154
|
+
}
|
155
|
+
}
|
156
|
+
PUPPET
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'detects one problem' do
|
160
|
+
expect(problems).to have(1).problems
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'case statement and an exec' do
|
165
|
+
let(:code) do
|
166
|
+
<<-PUPPET
|
167
|
+
class foo {
|
168
|
+
case bar {
|
169
|
+
baz : {
|
170
|
+
echo qux
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
exec { 'foo':
|
175
|
+
command => "echo bar",
|
176
|
+
}
|
177
|
+
}
|
178
|
+
PUPPET
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'detects zero problems' do
|
182
|
+
expect(problems).to have(0).problems
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -121,6 +121,14 @@ describe 'legacy_facts' do
|
|
121
121
|
expect(problems).to have(1).problem
|
122
122
|
end
|
123
123
|
end
|
124
|
+
|
125
|
+
context 'top scoped fact variable using unquoted legacy facts hash variable in interpolation' do
|
126
|
+
let(:code) { '$::facts[osfamily]' }
|
127
|
+
|
128
|
+
it 'detects a single problem' do
|
129
|
+
expect(problems).to have(1).problem
|
130
|
+
end
|
131
|
+
end
|
124
132
|
end
|
125
133
|
|
126
134
|
context 'with fix enabled' do
|
@@ -37,26 +37,10 @@ describe 'top_scope_facts' do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'fact variable using top scope' do
|
40
|
-
let(:code) { '$::
|
40
|
+
let(:code) { '$::fqdn' }
|
41
41
|
|
42
|
-
it '
|
43
|
-
expect(problems).to have(
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'creates a warning' do
|
47
|
-
expect(problems).to contain_warning(msg).on_line(1).in_column(1)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'fact variable using top scope with curly braces in double quote' do
|
52
|
-
let(:code) { '"${::operatingsystem}"' }
|
53
|
-
|
54
|
-
it 'onlies detect a single problem' do
|
55
|
-
expect(problems).to have(1).problem
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'creates a warning' do
|
59
|
-
expect(problems).to contain_warning(msg).on_line(1).in_column(4)
|
42
|
+
it 'does not detect a single problem' do
|
43
|
+
expect(problems).to have(0).problem
|
60
44
|
end
|
61
45
|
end
|
62
46
|
|
@@ -126,34 +110,6 @@ describe 'top_scope_facts' do
|
|
126
110
|
end
|
127
111
|
end
|
128
112
|
|
129
|
-
context 'fact variable using top scope' do
|
130
|
-
let(:code) { '$::operatingsystem' }
|
131
|
-
|
132
|
-
it 'onlies detect a single problem' do
|
133
|
-
expect(problems).to have(1).problem
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'fixes the problem' do
|
137
|
-
expect(problems).to contain_fixed(msg).on_line(1).in_column(1)
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'shoulds use the facts hash' do
|
141
|
-
expect(manifest).to eq("$facts['operatingsystem']")
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context 'fact variable using top scope with curly braces in double quote' do
|
146
|
-
let(:code) { '"${::operatingsystem}"' }
|
147
|
-
|
148
|
-
it 'fixes the problem' do
|
149
|
-
expect(problems).to contain_fixed(msg).on_line(1).in_column(4)
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'shoulds use the facts hash' do
|
153
|
-
expect(manifest).to eq('"${facts[\'operatingsystem\']}"')
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
113
|
context 'with custom top scope fact variables' do
|
158
114
|
before(:each) do
|
159
115
|
PuppetLint.configuration.top_scope_variables = ['location', 'role']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Sharpe
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-08-25 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: " Checks your Puppet manifests against the Puppetlabs style guide
|
16
16
|
and alerts you to any discrepancies.\n"
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/puppet-lint/plugins/check_strings/quoted_booleans.rb
|
67
67
|
- lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb
|
68
68
|
- lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb
|
69
|
+
- lib/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations.rb
|
69
70
|
- lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb
|
70
71
|
- lib/puppet-lint/plugins/check_variables/variable_is_lowercase.rb
|
71
72
|
- lib/puppet-lint/plugins/check_whitespace/140chars.rb
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- spec/unit/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb
|
140
141
|
- spec/unit/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb
|
141
142
|
- spec/unit/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb
|
143
|
+
- spec/unit/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations_spec.rb
|
142
144
|
- spec/unit/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb
|
143
145
|
- spec/unit/puppet-lint/plugins/check_variables/variable_is_lowercase_spec.rb
|
144
146
|
- spec/unit/puppet-lint/plugins/check_whitespace/140chars_spec.rb
|