puppet-lint-nine-check 0.3.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7bd04cd6c797fc8dfcfa90947cf9fa8464765f17da05128333b5d60ef24d7bd5
4
+ data.tar.gz: ebbb400e531834f99523e76881e0b874c0d0b341323714ed20d6555bcca2c981
5
+ SHA512:
6
+ metadata.gz: a195b46f95951a594d854b5301e5093734d044f1d24fc1d4c3fd1f1c72bfa2c482e6feefd625df9cd331255c10724135aa8da5f43a610d2d06e270b263b13f9a
7
+ data.tar.gz: 632e08c48a1a0a1549c14c4b7738a7a77390c4d09d80e55a95d0b517b8c68186fe030587d1244faf613eb61cf5cf50cc319180586f9ba7c7fb97a57516d06e98
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Nine Internet Solutions AG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ ## Overview
2
+
3
+ This linter will convert from legacy facts like `$::nine_location` or legacy hashed facts like `$facts['nine_location']` to the new structured facts like
4
+ `$facts['nine_metadata']['location']`.
5
+
6
+ ## Installing
7
+
8
+ ### From the command line
9
+
10
+ ```shell
11
+ $ gem install puppet-lint-nine-check
12
+ ```
13
+
14
+ ### In a Gemfile
15
+
16
+ ```ruby
17
+ gem 'puppet-lint-nine-check', :require => false
18
+ ```
19
+
20
+ #### Disabling the check
21
+
22
+ To disable this check, you can add `--no-nine` to your puppet-lint
23
+ command line.
24
+
25
+ ```shell
26
+ $ puppet-lint --no-nine path/to/file.pp
27
+ ```
28
+
29
+ Alternatively, if you’re calling puppet-lint via the Rake task, you should
30
+ insert the following line to your `Rakefile`.
31
+
32
+ ```ruby
33
+ PuppetLint.configuration.send('disable_nine')
34
+ ```
35
+
36
+ Alternatively, you can disable it directly in your puppet manifest.
37
+
38
+ ```puppet
39
+ # lint:ignore:nine
40
+ $package_name = $facts['operatingsystem'] {
41
+ 'CentOS' => 'httpd',
42
+ 'Debian' => 'apache2',
43
+ }
44
+ # lint:endignore
45
+ ```
@@ -0,0 +1,59 @@
1
+ # https://github.com/deanwilson/puppet-lint-concatenated_template_files-check/blob/4591aca68f0c30ffb52012db7e31a94b42830f0e/lib/puppet-lint/plugins/concatenated_template_files.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2016 Dean Wilson
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+ PuppetLint.new_check(:concatenated_template_files) do
26
+ def check
27
+ resource_indexes.each do |resource|
28
+ next unless resource[:type].value == "file"
29
+
30
+ content_tokens = resource[:param_tokens].select { |pt| pt.value == "content" }
31
+
32
+ content_tokens.each do |content_token|
33
+ value_token = content_token.next_code_token.next_code_token
34
+
35
+ next unless value_token.value == "template"
36
+
37
+ file_names = []
38
+
39
+ current_token = value_token.next_token
40
+ until current_token.type == :RPAREN
41
+ current_token = current_token.next_code_token
42
+ file_names << current_token.value if current_token.type == :SSTRING
43
+ end
44
+
45
+ next unless file_names.length > 1
46
+
47
+ warning = 'calling "template" with multiple files concatenates them into a single string'
48
+
49
+ notify :warning, {
50
+ message: warning,
51
+ line: value_token.line,
52
+ column: value_token.column,
53
+ param_token: content_token,
54
+ value_token: value_token
55
+ }
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,47 @@
1
+ # https://github.com/deanwilson/puppet-lint-explicit_hiera_class_param_lookup-check/blob/c2c23f4635017172dee1896c8e81c4d150586759/lib/puppet-lint/plugins/explicit_hiera_class_param_lookup.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2016 Dean Wilson
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+ PuppetLint.new_check(:explicit_hiera_class_param_lookup) do
26
+ def check
27
+ class_indexes.each do |class_idx|
28
+ next unless class_idx[:param_tokens].is_a? Array
29
+
30
+ tokens = class_idx[:param_tokens].select do |t|
31
+ (t.type == :NAME or t.type == :FUNCTION_NAME) and t.value == "hiera"
32
+ end
33
+
34
+ tokens.each do |token|
35
+ next unless token.next_code_token.type == :LPAREN
36
+
37
+ hiera_key = token.next_code_token.next_code_token
38
+
39
+ notify :error, {
40
+ message: "explicit hiera() lookup of #{hiera_key.value}",
41
+ line: hiera_key.line,
42
+ column: hiera_key.column
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ PuppetLint.new_check(:nine_legacy_facts) do
4
+ def legacy_fact_tokens
5
+ tokens.select { |x| [:VARIABLE, :UNENC_VARIABLE].include?(x.type) }
6
+ end
7
+
8
+ # These facts have a one to one correlation between a legacy fact and a new
9
+ # structured fact.
10
+ def fixable_facts
11
+ {
12
+ "nine_customer" => "facts['nine_metadata']['customer']",
13
+ "nine_location" => "facts['nine_metadata']['location']"
14
+ }
15
+ end
16
+
17
+ # A list of valid hash key token types
18
+ def hash_key_type?(type)
19
+ [
20
+ :STRING, # Double quoted string
21
+ :SSTRING, # Single quoted string
22
+ :NAME # Unquoted single word
23
+ ].include?(type)
24
+ end
25
+
26
+ def check
27
+ legacy_fact_tokens.each do |token|
28
+ fact_name = ""
29
+
30
+ # Get rid of the top scope before we do our work. We don't need to
31
+ # preserve it because it won't work with the new structured facts.
32
+ if token.value.start_with?("::")
33
+ fact_name = token.value.sub(/^::/, "")
34
+
35
+ # This matches using legacy facts in a the new structured fact. For
36
+ # example this would match 'uuid' in $facts['uuid'] so it can be converted
37
+ # to facts['dmi']['product']['uuid']"
38
+ elsif token.value == "facts"
39
+ fact_name = hash_key_for(token)
40
+
41
+ elsif token.value.start_with?("facts['")
42
+ fact_name = token.value.match(/facts\['(.*)'\]/)[1]
43
+ end
44
+
45
+ unless fixable_facts.include?(fact_name)
46
+ next
47
+ end
48
+
49
+ notify :warning,
50
+ message: "legacy fact",
51
+ line: token.line,
52
+ column: token.column,
53
+ token: token,
54
+ fact_name: fact_name
55
+ end
56
+ end
57
+
58
+ # If the variable is using the $facts hash represented internally by multiple
59
+ # tokens, this helper simplifies accessing the hash key.
60
+ def hash_key_for(token)
61
+ lbrack_token = token.next_code_token
62
+ return "" unless lbrack_token && lbrack_token.type == :LBRACK
63
+
64
+ key_token = lbrack_token.next_code_token
65
+ return "" unless key_token && hash_key_type?(key_token.type)
66
+
67
+ key_token.value
68
+ end
69
+
70
+ def fix(problem)
71
+ fact_name = problem[:fact_name]
72
+
73
+ # Check if the variable is using the $facts hash represented internally by
74
+ # multiple tokens and remove the tokens for the old legacy key if so.
75
+ if problem[:token].value == "facts"
76
+ loop do
77
+ t = problem[:token].next_token
78
+ remove_token(t)
79
+ break if t.type == :RBRACK
80
+ end
81
+ end
82
+
83
+ problem[:token].value = fixable_facts[fact_name] if fixable_facts.include?(fact_name)
84
+ end
85
+ end
@@ -0,0 +1,41 @@
1
+ # https://github.com/rodjek/puppet-lint-trailing_newline-check/blob/6bfdd76e53a509190f95273914a754ca21e3f2f0/spec/puppet-lint/plugins/check_trailing_newline_spec.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2014 Tim Sharpe
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+ PuppetLint.new_check(:trailing_newline) do
26
+ def check
27
+ last_token = tokens.last
28
+
29
+ unless last_token.type == :NEWLINE
30
+ notify :warning, {
31
+ message: "expected newline at the end of the file",
32
+ line: last_token.line,
33
+ column: manifest_lines.last.length
34
+ }
35
+ end
36
+ end
37
+
38
+ def fix(problem)
39
+ tokens << PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0)
40
+ end
41
+ end
@@ -0,0 +1,49 @@
1
+ # https://github.com/deanwilson/puppet-lint-world_writable_files-check/blob/a0956e31062d792740caa1dac30483110a39e375/lib/puppet-lint/plugins/world_writable_files.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2016 Dean Wilson
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+ PuppetLint.new_check(:world_writable_files) do
26
+ def check
27
+ resource_indexes.each do |resource|
28
+ next unless resource[:type].value == "file"
29
+
30
+ param_tokens = resource[:param_tokens].select { |pt| pt.value == "mode" }
31
+
32
+ param_tokens.each do |param_token|
33
+ # get the file modes value
34
+ value_token = param_token.next_code_token.next_code_token
35
+
36
+ # we only work with octal for now - also stops file { mode => undef }
37
+ break if !/^\d+$/.match?(value_token.value)
38
+ break if /\d+[^2367]$/.match?(value_token.value)
39
+
40
+ notify :warning, {
41
+ message: "files should not be created with world writable permissions",
42
+ line: value_token.line,
43
+ column: value_token.column,
44
+ token: value_token
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe "concatenated_template_files" do
4
+ let(:msg) { 'calling "template" with multiple files concatenates them into a single string' }
5
+
6
+ context "when the manifest has no file resources" do
7
+ let(:code) do
8
+ <<-TEST_CLASS
9
+ class no_file_resource {
10
+ host { 'syslog':
11
+ ip => '10.10.10.10',
12
+ }
13
+ }
14
+ TEST_CLASS
15
+ end
16
+
17
+ it "does not detect any problems" do
18
+ expect(problems.size).to eq(0)
19
+ end
20
+ end
21
+
22
+ context "with file resource but no template call" do
23
+ context "when the template has a relative module path" do
24
+ let(:code) do
25
+ <<-TEST_CLASS
26
+ class template_tester {
27
+ file { '/tmp/template':
28
+ content => 'A static string',
29
+ }
30
+ }
31
+ TEST_CLASS
32
+ end
33
+
34
+ it "detects no problems" do
35
+ expect(problems.size).to eq(0)
36
+ end
37
+ end
38
+ end
39
+
40
+ context "when template function is passed one filename" do
41
+ let(:code) do
42
+ <<-TEST_CLASS
43
+ class single_templated_file {
44
+ file { '/tmp/templated':
45
+ content => template('mymodule/single_file.erb'),
46
+ }
47
+ }
48
+ TEST_CLASS
49
+ end
50
+
51
+ it "does not detect any problems" do
52
+ expect(problems.size).to eq(0)
53
+ end
54
+ end
55
+
56
+ context "when template function is passed multiple filenames" do
57
+ let(:code) do
58
+ <<-TEST_CLASS
59
+ class multi_templated_file {
60
+ file { '/tmp/templated':
61
+ content => template('mymodule/first_file.erb', 'mymodule/second_file.erb'),
62
+ }
63
+ }
64
+ TEST_CLASS
65
+ end
66
+
67
+ it "detects a single problem" do
68
+ expect(problems.size).to eq(1)
69
+ end
70
+
71
+ it "creates a warning" do
72
+ expect(problems).to contain_warning(msg).on_line(3).in_column(24)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ describe "explicit_hiera_class_param_lookup" do
4
+ context "when class has no explicit hiera() lookups" do
5
+ let(:code) do
6
+ <<-TEST_CLASS
7
+ class no_explicit_lookups(
8
+ $my_content = undef
9
+ ) {
10
+ file { '/tmp/foo':
11
+ content => 'bar',
12
+ }
13
+ }
14
+ TEST_CLASS
15
+ end
16
+
17
+ it "does not detect any problems" do
18
+ expect(problems.size).to eq(0)
19
+ end
20
+ end
21
+
22
+ context "when class has an explicit hiera() lookup" do
23
+ let(:msg) { "explicit hiera() lookup of my::nested::key" }
24
+
25
+ let(:code) do
26
+ <<-TEST_CLASS
27
+ class no_explicit_lookups(
28
+ $my_content = hiera('my::nested::key', 'baz')
29
+ ) {
30
+ file { '/tmp/foo':
31
+ content => $my_content,
32
+ }
33
+ }
34
+ TEST_CLASS
35
+ end
36
+
37
+ it "detects a single problem" do
38
+ expect(problems.size).to eq(1)
39
+ end
40
+
41
+ it "creates an error" do
42
+ expect(problems).to contain_error(msg).on_line(2).in_column(31)
43
+ end
44
+ end
45
+
46
+ ### Reported issues
47
+ context "with an empty class with inherit and no explicit hiera() lookups" do
48
+ let(:code) do
49
+ <<-TEST_CLASS
50
+ class ig::base::freebsd inherits ig::base { }
51
+ TEST_CLASS
52
+ end
53
+
54
+ it "does not detect any problems" do
55
+ expect(problems.size).to eq(0)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "nine_legacy_facts" do
6
+ let(:msg) { "legacy fact" }
7
+ context "with fix disabled" do
8
+ context "fact variable using modern $facts['nine_metadata']['location'] hash" do
9
+ let(:code) { "$facts['nine_metadata']['location']" }
10
+
11
+ it "should not detect any problems" do
12
+ expect(problems.size).to eq(0)
13
+ end
14
+ end
15
+
16
+ context "fact variable using legacy $nine_location" do
17
+ let(:code) { "$nine_location" }
18
+
19
+ it "should not detect any problems" do
20
+ expect(problems.size).to eq(0)
21
+ end
22
+ end
23
+
24
+ context "fact variable using legacy $facts['nine_location']" do
25
+ let(:code) { "$facts['nine_location']" }
26
+
27
+ it "should only detect a single problem" do
28
+ expect(problems.size).to eq(1)
29
+ end
30
+ end
31
+
32
+ context "fact variable using legacy $::nine_location" do
33
+ let(:code) { "$::nine_location" }
34
+
35
+ it "should only detect a single problem" do
36
+ expect(problems.size).to eq(1)
37
+ end
38
+ end
39
+
40
+ context "fact variable using legacy $::nine_location" do
41
+ let(:code) { "$::nine_location" }
42
+
43
+ it "should only detect a single problem" do
44
+ expect(problems.size).to eq(1)
45
+ end
46
+ end
47
+
48
+ context "fact variable using legacy $facts['nine_location']" do
49
+ let(:code) { "$facts['nine_location']" }
50
+
51
+ it "should only detect a single problem" do
52
+ expect(problems.size).to eq(1)
53
+ end
54
+ end
55
+
56
+ context "fact variable using legacy facts hash variable in interpolation" do
57
+ let(:code) { %("${facts['nine_location']}") }
58
+
59
+ it "detects a single problem" do
60
+ expect(problems.size).to eq(1)
61
+ end
62
+ end
63
+ end
64
+
65
+ context "with fix enabled" do
66
+ before do
67
+ PuppetLint.configuration.fix = true
68
+ end
69
+
70
+ after do
71
+ PuppetLint.configuration.fix = false
72
+ end
73
+
74
+ context "fact variable using modern $facts['nine_metadata']['location'] hash" do
75
+ let(:code) { "$facts['nine_metadata']['location']" }
76
+
77
+ it "should not detect any problems" do
78
+ expect(problems.size).to eq(0)
79
+ end
80
+ end
81
+
82
+ context "fact variable using legacy $nine_location" do
83
+ let(:code) { "$nine_location" }
84
+
85
+ it "should not detect any problems" do
86
+ expect(problems.size).to eq(0)
87
+ end
88
+ end
89
+
90
+ context "fact variable using legacy $facts['nine_location']" do
91
+ let(:code) { "$facts['nine_location']" }
92
+
93
+ it "should only detect a single problem" do
94
+ expect(problems.size).to eq(1)
95
+ end
96
+
97
+ it "should fix the problem" do
98
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(1)
99
+ end
100
+
101
+ it "should use the facts hash" do
102
+ expect(manifest).to eq("$facts['nine_metadata']['location']")
103
+ end
104
+ end
105
+
106
+ context "fact variable using legacy $::nine_location" do
107
+ let(:code) { "$::nine_location" }
108
+
109
+ it "should only detect a single problem" do
110
+ expect(problems.size).to eq(1)
111
+ end
112
+
113
+ it "should fix the problem" do
114
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(1)
115
+ end
116
+
117
+ it "should use the facts hash" do
118
+ expect(manifest).to eq("$facts['nine_metadata']['location']")
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,65 @@
1
+ require "spec_helper"
2
+
3
+ describe "trailing_newline" do
4
+ let(:msg) { "expected newline at the end of the file" }
5
+
6
+ context "with fix disabled" do
7
+ context "code not ending with a newline" do
8
+ let(:code) { "'test'" }
9
+
10
+ it "should detect a single problem" do
11
+ expect(problems.size).to eq(1)
12
+ end
13
+
14
+ it "should create a warning" do
15
+ expect(problems).to contain_warning(msg).on_line(1).in_column(6)
16
+ end
17
+ end
18
+
19
+ context "code ending with a newline" do
20
+ let(:code) { "'test'\n" }
21
+
22
+ it "should not detect any problems" do
23
+ expect(problems.size).to eq(0)
24
+ end
25
+ end
26
+ end
27
+
28
+ context "with fix enabled" do
29
+ before do
30
+ PuppetLint.configuration.fix = true
31
+ end
32
+
33
+ after do
34
+ PuppetLint.configuration.fix = false
35
+ end
36
+
37
+ context "code not ending in a newline" do
38
+ let(:code) { "'test'" }
39
+
40
+ it "should only detect a single problem" do
41
+ expect(problems.size).to eq(1)
42
+ end
43
+
44
+ it "should fix the problem" do
45
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(6)
46
+ end
47
+
48
+ it "should add a newline to the end of the manifest" do
49
+ expect(manifest).to eq("'test'\n")
50
+ end
51
+ end
52
+
53
+ context "code ending in a newline" do
54
+ let(:code) { "'test'\n" }
55
+
56
+ it "should not detect any problems" do
57
+ expect(problems.size).to eq(0)
58
+ end
59
+
60
+ it "should not modify the manifest" do
61
+ expect(manifest).to eq(code)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe "world_writable_files" do
4
+ context "when the manifest has no file resources" do
5
+ let(:code) do
6
+ <<-TEST_CLASS
7
+ class no_file_resource {
8
+ host { 'syslog':
9
+ ip => '10.10.10.10',
10
+ }
11
+ }
12
+ TEST_CLASS
13
+ end
14
+
15
+ it "does not detect any problems" do
16
+ expect(problems.size).to eq(0)
17
+ end
18
+ end
19
+
20
+ context "when file resource has a mode of 640" do
21
+ let(:code) do
22
+ <<-TEST_CLASS
23
+ class locked_down_file {
24
+ file { '/tmp/locked_down':
25
+ ensure => 'file',
26
+ mode => '0640',
27
+ }
28
+ }
29
+ TEST_CLASS
30
+ end
31
+
32
+ it "does not detect any problems" do
33
+ expect(problems.size).to eq(0)
34
+ end
35
+ end
36
+
37
+ context "when file has a mode of undef" do
38
+ let(:code) do
39
+ <<-TEST_CLASS
40
+ class undef_file_mode {
41
+ file { '/tmp/undef_file_mode':
42
+ ensure => 'file',
43
+ mode => undef,
44
+ }
45
+ }
46
+ TEST_CLASS
47
+ end
48
+
49
+ it "does not detect any problems" do
50
+ expect(problems.size).to eq(0)
51
+ end
52
+ end
53
+
54
+ context "when file has a world writable octal mode of 666" do
55
+ let(:msg) { "files should not be created with world writable permissions" }
56
+ let(:code) do
57
+ <<-TEST_CLASS
58
+ class locked_down_file {
59
+ file { '/tmp/open_octal':
60
+ ensure => 'file',
61
+ mode => '0666',
62
+ }
63
+ }
64
+ TEST_CLASS
65
+ end
66
+
67
+ it "detects a problem" do
68
+ expect(problems.size).to eq(1)
69
+ end
70
+
71
+ it "creates a warning" do
72
+ expect(problems).to contain_warning(msg).on_line(4).in_column(23)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "puppet-lint"
4
+
5
+ PuppetLint::Plugins.load_spec_helper
6
+
7
+ RSpec.configure do |config|
8
+ config.formatter = :documentation
9
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-lint-nine-check
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Nine Internet Solutions AG
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-10-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: puppet-lint
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-json_expectations
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-collection_matchers
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: |2
112
+ A pupet-lint to check you are not using Nine legacy facts like `$::nine_location`
113
+ or `$facts['nine_location']`. You should use the new structured facts like
114
+ `$facts['nine_metadata']['location']` instead.
115
+ email:
116
+ - support@nine.ch
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - LICENSE
122
+ - README.md
123
+ - lib/puppet-lint/plugins/concatenated_template_files.rb
124
+ - lib/puppet-lint/plugins/explicit_hiera_class_param_lookup.rb
125
+ - lib/puppet-lint/plugins/nine_legacy_facts.rb
126
+ - lib/puppet-lint/plugins/trailing_newline.rb
127
+ - lib/puppet-lint/plugins/world_writable_files.rb
128
+ - spec/puppet-lint/plugins/concatenated_template_files_spec.rb
129
+ - spec/puppet-lint/plugins/explicit_hiera_class_param_lookup_spec.rb
130
+ - spec/puppet-lint/plugins/nine_legacy_facts_spec.rb
131
+ - spec/puppet-lint/plugins/trailing_newline_spec.rb
132
+ - spec/puppet-lint/plugins/world_writable_files_spec.rb
133
+ - spec/spec_helper.rb
134
+ homepage: https://gitlab.nine.ch/managed-services/puppet/tools/puppet-lint-nine-check
135
+ licenses:
136
+ - MIT
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 2.7.0
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubygems_version: 3.4.10
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: A puppet-lint plugin for different checks used at Nine.
157
+ test_files: []