puppet-lint-nine-check 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: []