puppet-lint-security-plugins 0.1.6
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +90 -0
- data/lib/puppet-lint-security-plugins.rb +2 -0
- data/lib/puppet-lint/plugins/check_class_or_define_parameter_in_exec.rb +36 -0
- data/lib/puppet-lint/plugins/check_security_apache_bad_cipher.rb +28 -0
- data/lib/puppet-lint/plugins/check_security_apache_no_ssl_vhost.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_apt_no_key.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_eval_in_erb.rb +21 -0
- data/lib/puppet-lint/plugins/check_security_file_with_setgid_permission.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_file_with_setuid_permission.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_file_with_world_permissions.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_firewall_any_any_allow.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_firewall_any_any_deny.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_firewall_dns_used.rb +30 -0
- data/lib/puppet-lint/plugins/check_security_firewall_puppetmaster_any_deny.rb +33 -0
- data/lib/puppet-lint/plugins/check_security_package_pinned_version.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_password_in_code.rb +31 -0
- data/lib/puppet-lint/plugins/check_security_password_variable_in_exec.rb +22 -0
- data/lib/puppet-lint/plugins/check_security_regex_unspecific.rb +23 -0
- data/lib/puppet-lint/plugins/check_security_service_mysql_disabled.rb +22 -0
- data/lib/puppet-lint/plugins/check_security_service_puppetmaster_disabled.rb +24 -0
- data/lib/puppet-lint/plugins/check_security_ssh_root_allowed.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_sudo_with_world_nopasswd.rb +23 -0
- data/lib/puppet-lint/plugins/check_security_tidy_all_files.rb +20 -0
- data/lib/puppet-lint/plugins/check_security_tidy_matches_greedy.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_tidy_recurse.rb +21 -0
- data/lib/puppet-lint/plugins/check_security_user_with_id_0_created.rb +28 -0
- data/lib/puppet-lint/security.rb +280 -0
- data/spec/puppet-lint/plugins/check_class_or_define_parameter_in_exec_spec.rb +85 -0
- data/spec/puppet-lint/plugins/check_security_apache_bad_cipher_spec.rb +49 -0
- data/spec/puppet-lint/plugins/check_security_apache_no_ssl_vhost_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_apt_absent_no_key_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_security_apt_no_key_spec.rb +38 -0
- data/spec/puppet-lint/plugins/check_security_dir_guid_permissions_spec.rb +49 -0
- data/spec/puppet-lint/plugins/check_security_dir_world_permissions_spec.rb +39 -0
- data/spec/puppet-lint/plugins/check_security_eval_in_erb_spec.rb +35 -0
- data/spec/puppet-lint/plugins/check_security_file_suid_permissions_spec.rb +48 -0
- data/spec/puppet-lint/plugins/check_security_file_with_setgid_permission_spec.rb +59 -0
- data/spec/puppet-lint/plugins/check_security_file_with_setuid_permission_spec.rb +59 -0
- data/spec/puppet-lint/plugins/check_security_file_with_world_permissions_spec.rb +62 -0
- data/spec/puppet-lint/plugins/check_security_file_world_and_guid_permissions_spec.rb +43 -0
- data/spec/puppet-lint/plugins/check_security_firewall_any_any_allow_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_security_firewall_any_any_deny_spec.rb +124 -0
- data/spec/puppet-lint/plugins/check_security_firewall_dns_used_spec.rb +77 -0
- data/spec/puppet-lint/plugins/check_security_firewall_puppetmaster_any_deny_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_package_pinned_version_spec.rb +43 -0
- data/spec/puppet-lint/plugins/check_security_password_in_code_spec.rb +55 -0
- data/spec/puppet-lint/plugins/check_security_password_variable_in_exec_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_security_regex_unspecific_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_service_mysql_disabled_spec.rb +54 -0
- data/spec/puppet-lint/plugins/check_security_service_puppetmaster_disabled_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_ssh_root_allowed_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_ssh_server_root_allowed_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_sudo_with_world_nopasswd_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_tidy_all_files_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_security_tidy_matches_greedy_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_security_tidy_recurse_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_security_user_with_id_0_created_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- metadata +232 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches package resources with specified version number
|
4
|
+
PuppetLint.new_check(:security_package_pinned_version) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
|
8
|
+
check_resource_index(
|
9
|
+
:resource_type => 'package',
|
10
|
+
:severity => :warning,
|
11
|
+
:message => 'Package version pinned (security!)'
|
12
|
+
) do |rule|
|
13
|
+
|
14
|
+
ensures = get_value_token_for_parameter(rule[:tokens],'ensure')
|
15
|
+
|
16
|
+
valid_values=['latest','purged','installed','present','installed','absent','held']
|
17
|
+
|
18
|
+
ensures.find_all do |token|
|
19
|
+
not valid_values.include? token.value
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches variable definitions wich may store passwords in clear text
|
4
|
+
PuppetLint.new_check(:security_password_in_code) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
passwords=/\A.*(passwor[dt]|_pwd?).*\z/i
|
8
|
+
|
9
|
+
variables_with_passwords=tokens.find_all do |token|
|
10
|
+
if token.type == :VARIABLE and token.value =~ passwords
|
11
|
+
value_token=get_variable_value_for(token) # maybe nil, if just a class parameter
|
12
|
+
end
|
13
|
+
is_a_good_password_variable = ( value_token.nil? or
|
14
|
+
value_token.value == 'hiera' or
|
15
|
+
value_token.value.empty? or
|
16
|
+
(
|
17
|
+
value_token.type != :STRING and
|
18
|
+
value_token.type != :SSTRING
|
19
|
+
)
|
20
|
+
)
|
21
|
+
not is_a_good_password_variable
|
22
|
+
end
|
23
|
+
|
24
|
+
bulk_notify(
|
25
|
+
:result => variables_with_passwords,
|
26
|
+
:severity => :error,
|
27
|
+
:message => 'Possible password in code detected (security!)'
|
28
|
+
)
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches class or defined_type parameters used in exec
|
4
|
+
PuppetLint.new_check(:security_password_variable_in_exec) do
|
5
|
+
def check
|
6
|
+
|
7
|
+
check_resource_index(
|
8
|
+
:resource_type => 'exec',
|
9
|
+
:severity => :error,
|
10
|
+
:message => 'Possible password variable in exec used (security!)'
|
11
|
+
) do |rule|
|
12
|
+
|
13
|
+
passwords=/\A.*(passwor[dt]|_pwd?).*\z/i
|
14
|
+
|
15
|
+
command_tokens=get_value_token_for_parameter(rule[:tokens],'command')
|
16
|
+
command_tokens.find_all do |token|
|
17
|
+
token.type == :VARIABLE and token.value =~ passwords
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches regular expression without start or end of string (\A,\z)
|
4
|
+
# or line (^,$) range markers
|
5
|
+
PuppetLint.new_check(:security_regex_unspecific) do
|
6
|
+
|
7
|
+
def check
|
8
|
+
|
9
|
+
start_or_end_of_line_or_string_used = /\A(\\A|\^).*(\\z|\$)\z/
|
10
|
+
|
11
|
+
result = tokens.find_all do |token|
|
12
|
+
token.type == :REGEX and
|
13
|
+
token.value !~ start_or_end_of_line_or_string_used
|
14
|
+
end
|
15
|
+
|
16
|
+
bulk_notify(
|
17
|
+
:result => result,
|
18
|
+
:severity => :warning,
|
19
|
+
:message => 'Unspecific regex used, maybe too much is matched.'
|
20
|
+
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches class or defined_type parameters used in exec
|
4
|
+
PuppetLint.new_check(:security_service_mysql_disabled) do
|
5
|
+
def check
|
6
|
+
|
7
|
+
check_resource_index(
|
8
|
+
:resource_type => 'service',
|
9
|
+
:severity => :warning,
|
10
|
+
:message => 'MySQL service disabled (security!)'
|
11
|
+
) do |rule|
|
12
|
+
|
13
|
+
value_tokens=get_value_token_for_parameter(rule[:tokens],'ensure')
|
14
|
+
title_token = get_resource_title_for(rule)
|
15
|
+
title = title_token.value unless title_token.nil?
|
16
|
+
value_tokens.find_all do |token|
|
17
|
+
token.value == 'stopped' and title == 'mysql'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches class or defined_type parameters used in exec
|
4
|
+
PuppetLint.new_check(:security_service_puppetmaster_disabled) do
|
5
|
+
def check
|
6
|
+
|
7
|
+
check_resource_index(
|
8
|
+
:resource_type => 'service',
|
9
|
+
:severity => :warning,
|
10
|
+
:message => 'Puppetmaster service disabled (security!)'
|
11
|
+
) do |rule|
|
12
|
+
|
13
|
+
value_tokens=get_value_token_for_parameter(rule[:tokens],'ensure')
|
14
|
+
|
15
|
+
title_token = get_resource_title_for(rule)
|
16
|
+
title = title_token.value unless title_token.nil?
|
17
|
+
|
18
|
+
value_tokens.find_all do |token|
|
19
|
+
token.value == 'stopped' and title == 'puppetmaster'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Needed: saz/ssh module (https://forge.puppetlabs.com/saz/ssh)
|
4
|
+
# Matches ssh resources with PermitRootLogin enabled
|
5
|
+
PuppetLint.new_check(:security_ssh_root_allowed) do
|
6
|
+
|
7
|
+
def check
|
8
|
+
|
9
|
+
check_resource_index(
|
10
|
+
:resource_type => ['ssh','ssh::server'],
|
11
|
+
:severity => :error,
|
12
|
+
:message => 'SSH root login allowed (security!)'
|
13
|
+
) do |rule|
|
14
|
+
|
15
|
+
options = get_hash_tokens_for_parameter(rule[:tokens],'options')#.each do |option|
|
16
|
+
options += get_hash_tokens_for_parameter(rule[:tokens],'server_options')#.each do |option|
|
17
|
+
permit_root_logins = get_value_token_for_parameter(options,'PermitRootLogin')
|
18
|
+
|
19
|
+
permit_root_logins.find_all do |token|
|
20
|
+
['true','1','yes'].include? token.value
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Needed: saz/sudo module (https://forge.puppetlabs.com/saz/sudo)
|
4
|
+
# Matches sudo resources with world root permissions
|
5
|
+
PuppetLint.new_check(:security_sudo_with_world_nopasswd) do
|
6
|
+
|
7
|
+
def check
|
8
|
+
bad_sudo_regex=/\AALL.*NOPASSWD.*\z/i
|
9
|
+
|
10
|
+
check_resource_index(
|
11
|
+
:resource_type => 'sudo::conf',
|
12
|
+
:severity => :error,
|
13
|
+
:message => 'Sudo access with world permissions detected (security!)'
|
14
|
+
) do |rule|
|
15
|
+
|
16
|
+
sudo_rules=get_value_token_for_parameter(rule[:tokens],'content')
|
17
|
+
sudo_rules.find_all do |token|
|
18
|
+
token.value =~ bad_sudo_regex
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches tidy resources without age and size parameters
|
4
|
+
PuppetLint.new_check(:security_tidy_all_files) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
|
8
|
+
check_resource_index(
|
9
|
+
:resource_type => 'tidy',
|
10
|
+
:severity => :warning,
|
11
|
+
:message => 'Purging all files, be warned!'
|
12
|
+
) do |rule|
|
13
|
+
|
14
|
+
ages=get_value_token_for_parameter(rule[:tokens],'age')
|
15
|
+
sizes=get_value_token_for_parameter(rule[:tokens],'size')
|
16
|
+
rule[:tokens].first if (ages + sizes).empty?
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches tidy resources with 'match' parameter equals '*'
|
4
|
+
PuppetLint.new_check(:security_tidy_matches_greedy) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
|
8
|
+
check_resource_index(
|
9
|
+
:resource_type => 'tidy',
|
10
|
+
:severity => :warning,
|
11
|
+
:message => 'This will delete all files, be warned!'
|
12
|
+
) do |rule|
|
13
|
+
|
14
|
+
tokens=rule[:tokens]
|
15
|
+
if value_is_array?(tokens,'matches')
|
16
|
+
matches=get_array_tokens_for_parameter(tokens,'matches')
|
17
|
+
else
|
18
|
+
matches=get_value_token_for_parameter(tokens,'matches')
|
19
|
+
end
|
20
|
+
matches.find_all do |token|
|
21
|
+
token.value == '*'
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches tidy resources with recurse parameter enabled
|
4
|
+
PuppetLint.new_check(:security_tidy_recurse) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
|
8
|
+
check_resource_index(
|
9
|
+
:resource_type => 'tidy',
|
10
|
+
:severity => :warning,
|
11
|
+
:message => 'Purging files recurse, be warned!'
|
12
|
+
) do |rule|
|
13
|
+
|
14
|
+
recurses=get_value_token_for_parameter(rule[:tokens],'recurse')
|
15
|
+
recurses.find_all do |token|
|
16
|
+
['true','1','inf'].include? token.value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'puppet-lint-security-plugins'
|
2
|
+
|
3
|
+
# Matches user resources creating a non root user with id 0
|
4
|
+
PuppetLint.new_check(:security_user_with_id_0_created) do
|
5
|
+
|
6
|
+
def check
|
7
|
+
|
8
|
+
check_resource_index(
|
9
|
+
:resource_type => 'user',
|
10
|
+
:severity => :error,
|
11
|
+
:message => 'Another User with ID 0 would be created (security!)'
|
12
|
+
) do |rule|
|
13
|
+
|
14
|
+
title=get_resource_title_for(rule)
|
15
|
+
uids=get_value_token_for_parameter(rule[:tokens],'uid')
|
16
|
+
allowdupes=get_value_token_for_parameter(rule[:tokens],'allowdupe')
|
17
|
+
users=get_value_token_for_parameter(rule[:tokens],'name')
|
18
|
+
users << title
|
19
|
+
|
20
|
+
uid_zero=uids.find_all{|uid| uid.value == "0"}
|
21
|
+
allowdupe_true=allowdupes.find_all{|allowdupe| allowdupe.value == "true"}
|
22
|
+
|
23
|
+
rule[:tokens].first if (not users.include? 'root') and
|
24
|
+
(not uid_zero.empty?) and (not allowdupe_true.empty?)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
# Defines helper methods for check plugins
|
2
|
+
class PuppetLint::CheckPlugin
|
3
|
+
|
4
|
+
# This types represent valid values for variables and parameters
|
5
|
+
VALID_CONTENT_TOKENS=[:NAME,:SSTRING,:STRING,:NUMBER,:TRUE,:FALSE,:DQPRE,:DQMID,:DQPOST,:VARIABLE]
|
6
|
+
|
7
|
+
# Checks if given resource is defined in given class or define
|
8
|
+
#
|
9
|
+
# @param resource [Hash] puppet-lint resource_index hash
|
10
|
+
# @param class_or_define [Hash] puppet-lint class_index or defined_type_index hash
|
11
|
+
# @return [Boolean] it is defined inside or not
|
12
|
+
def resource_in_class_or_define?(resource,class_or_define)
|
13
|
+
resource[:start] > class_or_define[:start] and
|
14
|
+
resource[:end] < class_or_define[:end]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Checks if given parameter of a puppet resource is an array
|
18
|
+
#
|
19
|
+
# @param tokens [Array] puppet-lint token objects
|
20
|
+
# @param parameter [String] search only mathing parameters
|
21
|
+
# @return [Boolean] it is an array or not
|
22
|
+
def value_is_array?(tokens,parameter)
|
23
|
+
values_with_lbracks=tokens.find_all do |token|
|
24
|
+
# match 'parameter => ['
|
25
|
+
token.type == :LBRACK and
|
26
|
+
token.prev_code_token.type == :FARROW and
|
27
|
+
token.prev_code_token.prev_code_token.value == parameter
|
28
|
+
end
|
29
|
+
not values_with_lbracks.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get array of tokens for given parameter out of puppet resource definition
|
33
|
+
#
|
34
|
+
# @param tokens [Array] puppet-lint token objects
|
35
|
+
# @param parameter [String] search only mathing parameters
|
36
|
+
# @return [Array] an array of matching token objects
|
37
|
+
def get_array_tokens_for_parameter(tokens,parameter)
|
38
|
+
get_tokens_between(tokens,:BRACK,parameter).reject do |token|
|
39
|
+
token.type == :COMMA
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get array of tokens with given parameter out of a hash
|
44
|
+
#
|
45
|
+
# @param tokens [Array] puppet-lint token objects
|
46
|
+
# @param parameter [String] search only mathing parameters
|
47
|
+
# @return [Array] an array of matching token objects
|
48
|
+
def get_hash_tokens_for_parameter(tokens,parameter)
|
49
|
+
get_tokens_between(tokens,:BRACE,parameter)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get array of tokens with given parameter out of any puppet block
|
53
|
+
#
|
54
|
+
# @param tokens [Array] puppet-lint token objects
|
55
|
+
# @param parameter [String] search only mathing parameters
|
56
|
+
# @return [Array] an array of matching token objects
|
57
|
+
def get_tokens_between(tokens,type,parameter)
|
58
|
+
brace_open=tokens.find do |token|
|
59
|
+
token.type == left(type) and
|
60
|
+
# Vorher kommt ein Pfeil, somit ist es der Wert eines Parmeters
|
61
|
+
token.prev_code_token.type == :FARROW and
|
62
|
+
# Vor dem Pfeil kommt der gesuchte Parameter
|
63
|
+
token.prev_code_token.prev_code_token.value == parameter
|
64
|
+
end
|
65
|
+
|
66
|
+
if brace_open.nil?
|
67
|
+
return []
|
68
|
+
else
|
69
|
+
return get_block_between(type,brace_open)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get resource block for given puppet resource name.
|
74
|
+
# Resource type is irrelevant
|
75
|
+
#
|
76
|
+
# @param resource_title [String] resource title of queried resource block
|
77
|
+
# @param token [PuppetLint::Lexer::Token] Token of a puppet resource
|
78
|
+
# @return [Array] an array of array with matching token objects
|
79
|
+
def get_resource_block_for(resource_title,token)
|
80
|
+
titles=title_tokens_with_block
|
81
|
+
|
82
|
+
titles.find_all do | hash |
|
83
|
+
hash[:title].value == resource_title
|
84
|
+
end.first.values.flatten
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get array of tokens with values of given parameter
|
89
|
+
#
|
90
|
+
# @param tokens [Array] puppet-lint token objects
|
91
|
+
# @param parameter [String] search only mathing parameters
|
92
|
+
# @return [Array] an array of matching token objects
|
93
|
+
def get_value_token_for_parameter(tokens,parameter)
|
94
|
+
value_starts_tokens=tokens.find_all do |token|
|
95
|
+
VALID_CONTENT_TOKENS.include? token.type and
|
96
|
+
# An arrow first indicates the value of a parameter
|
97
|
+
token.prev_code_token.type == :FARROW and
|
98
|
+
# The given parameter comes first, then the arrow
|
99
|
+
token.prev_code_token.prev_code_token.value == parameter
|
100
|
+
end
|
101
|
+
value_starts_tokens.map do |token|
|
102
|
+
if token.type==:DQPRE
|
103
|
+
t=[]
|
104
|
+
until token.type == :DQPOST
|
105
|
+
t << token
|
106
|
+
token=token.next_code_token
|
107
|
+
end
|
108
|
+
t
|
109
|
+
else
|
110
|
+
token
|
111
|
+
end
|
112
|
+
end.flatten
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get array of tokens with arguments of a puppet-function
|
116
|
+
#
|
117
|
+
# @param tokens [Array] puppet-lint token objects
|
118
|
+
# @param function [String] search only mathing functions
|
119
|
+
# @return [Array] an array of matching token objects
|
120
|
+
def get_argument_token_for_function(tokens,function)
|
121
|
+
lparen=tokens.find do |token|
|
122
|
+
token.type == :LPAREN and
|
123
|
+
token.prev_code_token.type == :NAME and
|
124
|
+
token.prev_code_token.value == function
|
125
|
+
end
|
126
|
+
|
127
|
+
if lparen.nil?
|
128
|
+
return []
|
129
|
+
else
|
130
|
+
return get_block_between(:PAREN,lparen)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get first token with begin of value to a given parameter token
|
135
|
+
#
|
136
|
+
# @param token [PuppetLint::Lexer::Token] Token of a parameter to a puppet resource
|
137
|
+
# @return [PuppetLint::Lexer::Token] Token with value (first token after equals
|
138
|
+
def get_variable_value_for(token)
|
139
|
+
if token.type == :VARIABLE and token.next_code_token.type == :EQUALS
|
140
|
+
token=token.next_code_token
|
141
|
+
until token.next_code_token.nil? or VALID_CONTENT_TOKENS.include? token.type or token.type == :VARIABLE
|
142
|
+
token=token.next_code_token
|
143
|
+
end
|
144
|
+
return token
|
145
|
+
else
|
146
|
+
return nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Get Hash of titles and tokens of puppet manifest
|
151
|
+
#
|
152
|
+
# @return [Array] of [Hashes] with title as [PuppetLint::Lexer::Token] token
|
153
|
+
# and array of token with parameters as [PuppetLint::Lexer::Token]
|
154
|
+
def title_tokens_with_block
|
155
|
+
|
156
|
+
# Get all token blocks having between colon and semic or rbrace
|
157
|
+
title_tokens.map do |block_starter|
|
158
|
+
token_array=[]
|
159
|
+
t = block_starter.next_token
|
160
|
+
|
161
|
+
until [:SEMIC,:RBRACE].include? t.type
|
162
|
+
token_array << t unless t.type == :COLON
|
163
|
+
t = t.next_token
|
164
|
+
end
|
165
|
+
|
166
|
+
{
|
167
|
+
:title => block_starter,
|
168
|
+
:tokens => token_array
|
169
|
+
}
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
# Get resource title for rule
|
176
|
+
#
|
177
|
+
# @param [Hash] representing a resource_index
|
178
|
+
# @return [String] resource title of given rule
|
179
|
+
def get_resource_title_for(rule)
|
180
|
+
title_token=title_tokens_with_block.find do |h|
|
181
|
+
h[:tokens].first == rule[:tokens].first
|
182
|
+
end
|
183
|
+
title_token[:title] unless title_token.nil?
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
# Warps puppet-lint notify and generates notifies for array of problems
|
188
|
+
#
|
189
|
+
# @param hash [Hash] Hash with options
|
190
|
+
# @option hash [Array] :result Array of PuppetLint::Lexer::Token containing problems
|
191
|
+
# @option hash [Symbol] :severity Severity of problem (:warning or :critical)
|
192
|
+
# @option hash [String] :message Description of problem
|
193
|
+
#
|
194
|
+
# @return nothing
|
195
|
+
def bulk_notify(hash)
|
196
|
+
hash[:result].each do |v|
|
197
|
+
notify hash[:severity], {
|
198
|
+
:message => hash[:message],
|
199
|
+
:line => v.line,
|
200
|
+
:column => v.column,
|
201
|
+
}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Wrapper to check logic. Searches tokens matching given puppet resource or class.
|
206
|
+
#
|
207
|
+
# @param hash [Hash] Hash with options
|
208
|
+
# @option hash [Array] :resource_type Array of PuppetLint::Lexer::Token containing problems
|
209
|
+
# @option hash [Symbol] :severity Severity of problem (:warning or :critical)
|
210
|
+
# @option hash [String] :message Description of problem
|
211
|
+
#
|
212
|
+
# @return nothing
|
213
|
+
def check_resource_index(hash)
|
214
|
+
|
215
|
+
# Operate on arrays
|
216
|
+
unless hash[:resource_type].is_a? Array
|
217
|
+
resource_types=[hash[:resource_type]]
|
218
|
+
else
|
219
|
+
resource_types=hash[:resource_type]
|
220
|
+
end
|
221
|
+
|
222
|
+
rules=resource_indexes.find_all do |resource|
|
223
|
+
# Need to search resource titles, when not a predefined puppet resource
|
224
|
+
if resource[:type].type == :CLASS
|
225
|
+
resource_titles = title_tokens.map { |t| t.value }
|
226
|
+
diff_titles = (resource_types - resource_titles)
|
227
|
+
|
228
|
+
# Difference is smaler then original
|
229
|
+
# so some elements where substracted
|
230
|
+
diff_titles.count < resource_types.count
|
231
|
+
else
|
232
|
+
resource_types.include? resource[:type].value
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
result=rules.map do |rule|
|
237
|
+
yield rule
|
238
|
+
end.flatten.compact
|
239
|
+
|
240
|
+
bulk_notify(hash.merge(:result => result))
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
# Get array of tokens between braces
|
247
|
+
#
|
248
|
+
# @param type [Symbol] Caps symbol representing type of brace (:BRACE, :BRACK, :PAREN)
|
249
|
+
# @param start_token [PuppetLint::Lexer::Token] Token with opening brace
|
250
|
+
# @return [Array] an array of matching token objects
|
251
|
+
def get_block_between(type,start_token)
|
252
|
+
token_array=[]
|
253
|
+
t = start_token.next_code_token
|
254
|
+
brack_counter=1
|
255
|
+
until brack_counter==0
|
256
|
+
brack_counter -= 1 if t.next_code_token.type == right(type)
|
257
|
+
brack_counter += 1 if t.next_code_token.type == left(type)
|
258
|
+
token_array << t
|
259
|
+
t = t.next_code_token
|
260
|
+
end
|
261
|
+
return token_array
|
262
|
+
end
|
263
|
+
|
264
|
+
# Converts brace symbol to left/opening brace (prefixes 'L')
|
265
|
+
#
|
266
|
+
# @param type [Symbol] Caps symbol representing type of brace (:BRACE, :BRACK, :PAREN)
|
267
|
+
# @return [Symbol] Caps symbol with prefixed 'L'
|
268
|
+
def left(type)
|
269
|
+
("L"+type.to_s).to_sym
|
270
|
+
end
|
271
|
+
|
272
|
+
# Converts brace symbol to right/closing brace (prefixes 'R')
|
273
|
+
#
|
274
|
+
# @param type [Symbol] Caps symbol representing type of brace (:BRACE, :BRACK, :PAREN)
|
275
|
+
# @return [Symbol] Caps symbol with prefixed 'R'
|
276
|
+
def right(type)
|
277
|
+
("R"+type.to_s).to_sym
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|