inspec 0.14.8 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -2
  3. data/bin/inspec +3 -4
  4. data/examples/inheritance/README.md +19 -0
  5. data/examples/inheritance/controls/example.rb +11 -0
  6. data/examples/inheritance/inspec.yml +10 -0
  7. data/lib/bundles/inspec-compliance/cli.rb +1 -4
  8. data/lib/bundles/inspec-supermarket/cli.rb +1 -4
  9. data/lib/inspec/dsl.rb +48 -55
  10. data/lib/inspec/profile.rb +6 -2
  11. data/lib/inspec/profile_context.rb +21 -8
  12. data/lib/inspec/runner.rb +17 -12
  13. data/lib/inspec/runner_rspec.rb +1 -0
  14. data/lib/inspec/version.rb +1 -1
  15. data/lib/resources/apache.rb +20 -18
  16. data/lib/resources/apache_conf.rb +92 -90
  17. data/lib/resources/apt.rb +92 -90
  18. data/lib/resources/audit_policy.rb +35 -33
  19. data/lib/resources/auditd_conf.rb +41 -39
  20. data/lib/resources/auditd_rules.rb +155 -153
  21. data/lib/resources/bond.rb +1 -1
  22. data/lib/resources/bridge.rb +97 -95
  23. data/lib/resources/command.rb +47 -45
  24. data/lib/resources/csv.rb +23 -21
  25. data/lib/resources/directory.rb +1 -1
  26. data/lib/resources/etc_group.rb +116 -114
  27. data/lib/resources/file.rb +1 -1
  28. data/lib/resources/gem.rb +39 -37
  29. data/lib/resources/group.rb +100 -98
  30. data/lib/resources/host.rb +103 -101
  31. data/lib/resources/inetd_conf.rb +42 -40
  32. data/lib/resources/ini.rb +15 -13
  33. data/lib/resources/interface.rb +106 -104
  34. data/lib/resources/iptables.rb +36 -34
  35. data/lib/resources/json.rb +64 -62
  36. data/lib/resources/kernel_module.rb +30 -28
  37. data/lib/resources/kernel_parameter.rb +44 -42
  38. data/lib/resources/limits_conf.rb +41 -39
  39. data/lib/resources/login_def.rb +38 -36
  40. data/lib/resources/mount.rb +43 -41
  41. data/lib/resources/mysql.rb +67 -65
  42. data/lib/resources/mysql_conf.rb +89 -87
  43. data/lib/resources/mysql_session.rb +46 -44
  44. data/lib/resources/npm.rb +35 -33
  45. data/lib/resources/ntp_conf.rb +44 -42
  46. data/lib/resources/oneget.rb +46 -44
  47. data/lib/resources/os.rb +22 -20
  48. data/lib/resources/os_env.rb +47 -45
  49. data/lib/resources/package.rb +213 -211
  50. data/lib/resources/parse_config.rb +59 -57
  51. data/lib/resources/passwd.rb +89 -87
  52. data/lib/resources/pip.rb +60 -58
  53. data/lib/resources/port.rb +352 -350
  54. data/lib/resources/postgres.rb +26 -24
  55. data/lib/resources/postgres_conf.rb +66 -64
  56. data/lib/resources/postgres_session.rb +47 -45
  57. data/lib/resources/processes.rb +56 -54
  58. data/lib/resources/registry_key.rb +150 -148
  59. data/lib/resources/script.rb +30 -28
  60. data/lib/resources/security_policy.rb +56 -54
  61. data/lib/resources/service.rb +638 -636
  62. data/lib/resources/shadow.rb +98 -96
  63. data/lib/resources/ssh_conf.rb +58 -56
  64. data/lib/resources/user.rb +363 -361
  65. data/lib/resources/windows_feature.rb +46 -44
  66. data/lib/resources/xinetd.rb +111 -109
  67. data/lib/resources/yaml.rb +16 -14
  68. data/lib/resources/yum.rb +107 -105
  69. data/lib/utils/base_cli.rb +18 -0
  70. data/test/helper.rb +2 -2
  71. data/test/unit/profile_context_test.rb +1 -1
  72. data/test/unit/resources/file_test.rb +1 -1
  73. data/test/unit/resources/mount_test.rb +1 -1
  74. metadata +5 -2
@@ -76,6 +76,7 @@ module Inspec
76
76
  # @return [nil]
77
77
  def configure_output
78
78
  RSpec.configuration.add_formatter(@conf['format'] || 'progress')
79
+ RSpec.configuration.color = @conf['color']
79
80
 
80
81
  setup_reporting if @conf['report']
81
82
  end
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.14.8'.freeze
6
+ VERSION = '0.15.0'.freeze
7
7
  end
@@ -4,26 +4,28 @@
4
4
  # author: Dominik Richter
5
5
  # license: All rights reserved
6
6
 
7
- class Apache < Inspec.resource(1)
8
- name 'apache'
7
+ module Inspec::Resources
8
+ class Apache < Inspec.resource(1)
9
+ name 'apache'
9
10
 
10
- attr_reader :service, :conf_dir, :conf_path, :user
11
- def initialize
12
- case inspec.os[:family]
13
- when 'ubuntu', 'debian'
14
- @service = 'apache2'
15
- @conf_dir = '/etc/apache2/'
16
- @conf_path = File.join @conf_dir, 'apache2.conf'
17
- @user = 'www-data'
18
- else
19
- @service = 'httpd'
20
- @conf_dir = '/etc/httpd/'
21
- @conf_path = File.join @conf_dir, '/conf/httpd.conf'
22
- @user = 'apache'
11
+ attr_reader :service, :conf_dir, :conf_path, :user
12
+ def initialize
13
+ case inspec.os[:family]
14
+ when 'ubuntu', 'debian'
15
+ @service = 'apache2'
16
+ @conf_dir = '/etc/apache2/'
17
+ @conf_path = File.join @conf_dir, 'apache2.conf'
18
+ @user = 'www-data'
19
+ else
20
+ @service = 'httpd'
21
+ @conf_dir = '/etc/httpd/'
22
+ @conf_path = File.join @conf_dir, '/conf/httpd.conf'
23
+ @user = 'apache'
24
+ end
23
25
  end
24
- end
25
26
 
26
- def to_s
27
- 'Apache Environment'
27
+ def to_s
28
+ 'Apache Environment'
29
+ end
28
30
  end
29
31
  end
@@ -7,118 +7,120 @@
7
7
  require 'utils/simpleconfig'
8
8
  require 'utils/find_files'
9
9
 
10
- class ApacheConf < Inspec.resource(1)
11
- name 'apache_conf'
12
- desc 'Use the apache_conf InSpec audit resource to test the configuration settings for Apache. This file is typically located under /etc/apache2 on the Debian and Ubuntu platforms and under /etc/httpd on the Fedora, CentOS, Red Hat Enterprise Linux, and Arch Linux platforms. The configuration settings may vary significantly from platform to platform.'
13
- example "
14
- describe apache_conf do
15
- its('setting_name') { should eq 'value' }
16
- end
17
- "
10
+ module Inspec::Resources
11
+ class ApacheConf < Inspec.resource(1)
12
+ name 'apache_conf'
13
+ desc 'Use the apache_conf InSpec audit resource to test the configuration settings for Apache. This file is typically located under /etc/apache2 on the Debian and Ubuntu platforms and under /etc/httpd on the Fedora, CentOS, Red Hat Enterprise Linux, and Arch Linux platforms. The configuration settings may vary significantly from platform to platform.'
14
+ example "
15
+ describe apache_conf do
16
+ its('setting_name') { should eq 'value' }
17
+ end
18
+ "
18
19
 
19
- include FindFiles
20
+ include FindFiles
20
21
 
21
- def initialize(conf_path = nil)
22
- @conf_path = conf_path || inspec.apache.conf_path
23
- @conf_dir = File.dirname(@conf_path)
24
- @files_contents = {}
25
- @content = nil
26
- @params = nil
27
- read_content
28
- end
22
+ def initialize(conf_path = nil)
23
+ @conf_path = conf_path || inspec.apache.conf_path
24
+ @conf_dir = File.dirname(@conf_path)
25
+ @files_contents = {}
26
+ @content = nil
27
+ @params = nil
28
+ read_content
29
+ end
29
30
 
30
- def content
31
- @content ||= read_content
32
- end
31
+ def content
32
+ @content ||= read_content
33
+ end
33
34
 
34
- def params(*opts)
35
- @params || read_content
36
- res = @params
37
- opts.each do |opt|
38
- res = res[opt] unless res.nil?
35
+ def params(*opts)
36
+ @params || read_content
37
+ res = @params
38
+ opts.each do |opt|
39
+ res = res[opt] unless res.nil?
40
+ end
41
+ res
39
42
  end
40
- res
41
- end
42
43
 
43
- def method_missing(name)
44
- # ensure params are loaded
45
- @params || read_content
44
+ def method_missing(name)
45
+ # ensure params are loaded
46
+ @params || read_content
46
47
 
47
- # extract values
48
- @params[name.to_s] unless @params.nil?
49
- end
48
+ # extract values
49
+ @params[name.to_s] unless @params.nil?
50
+ end
50
51
 
51
- def filter_comments(data)
52
- content = ''
53
- data.each_line do |line|
54
- if !line.match(/^\s*#/)
55
- content << line
52
+ def filter_comments(data)
53
+ content = ''
54
+ data.each_line do |line|
55
+ if !line.match(/^\s*#/)
56
+ content << line
57
+ end
56
58
  end
59
+ content
57
60
  end
58
- content
59
- end
60
61
 
61
- def read_content
62
- @content = ''
63
- @params = {}
62
+ def read_content
63
+ @content = ''
64
+ @params = {}
64
65
 
65
- # skip if the main configuration file doesn't exist
66
- file = inspec.file(@conf_path)
67
- if !file.file?
68
- return skip_resource "Can't find file \"#{@conf_path}\""
69
- end
66
+ # skip if the main configuration file doesn't exist
67
+ file = inspec.file(@conf_path)
68
+ if !file.file?
69
+ return skip_resource "Can't find file \"#{@conf_path}\""
70
+ end
70
71
 
71
- raw_conf = file.content
72
- if raw_conf.empty? && file.size > 0
73
- return skip_resource("Can't read file \"#{@conf_path}\"")
74
- end
72
+ raw_conf = file.content
73
+ if raw_conf.empty? && file.size > 0
74
+ return skip_resource("Can't read file \"#{@conf_path}\"")
75
+ end
75
76
 
76
- to_read = [@conf_path]
77
- until to_read.empty?
78
- raw_conf = read_file(to_read[0])
79
- @content += raw_conf
80
-
81
- # parse include file parameters
82
- params = SimpleConfig.new(
83
- raw_conf,
84
- assignment_re: /^\s*(\S+)\s+(.*)\s*$/,
85
- multiple_values: true,
86
- ).params
87
- @params.merge!(params)
88
-
89
- to_read = to_read.drop(1)
90
- to_read += include_files(params).find_all do |fp|
91
- not @files_contents.key? fp
77
+ to_read = [@conf_path]
78
+ until to_read.empty?
79
+ raw_conf = read_file(to_read[0])
80
+ @content += raw_conf
81
+
82
+ # parse include file parameters
83
+ params = SimpleConfig.new(
84
+ raw_conf,
85
+ assignment_re: /^\s*(\S+)\s+(.*)\s*$/,
86
+ multiple_values: true,
87
+ ).params
88
+ @params.merge!(params)
89
+
90
+ to_read = to_read.drop(1)
91
+ to_read += include_files(params).find_all do |fp|
92
+ not @files_contents.key? fp
93
+ end
92
94
  end
95
+
96
+ # fiter comments
97
+ @content = filter_comments @content
98
+ @content
93
99
  end
94
100
 
95
- # fiter comments
96
- @content = filter_comments @content
97
- @content
98
- end
101
+ def include_files(params)
102
+ # see if there is more config files to include
103
+ include_files = params['Include'] || []
104
+ include_files_optional = params['IncludeOptional'] || []
99
105
 
100
- def include_files(params)
101
- # see if there is more config files to include
102
- include_files = params['Include'] || []
103
- include_files_optional = params['IncludeOptional'] || []
106
+ includes = []
107
+ (include_files + include_files_optional).each do |f|
108
+ id = File.join(@conf_dir, f)
109
+ files = find_files(id, depth: 1, type: 'file')
104
110
 
105
- includes = []
106
- (include_files + include_files_optional).each do |f|
107
- id = File.join(@conf_dir, f)
108
- files = find_files(id, depth: 1, type: 'file')
111
+ includes.push(files) if files
112
+ end
109
113
 
110
- includes.push(files) if files
114
+ # [].flatten! == nil
115
+ includes.flatten! || []
111
116
  end
112
117
 
113
- # [].flatten! == nil
114
- includes.flatten! || []
115
- end
116
-
117
- def read_file(path)
118
- @files_contents[path] ||= inspec.file(path).content
119
- end
118
+ def read_file(path)
119
+ @files_contents[path] ||= inspec.file(path).content
120
+ end
120
121
 
121
- def to_s
122
- "Apache Config #{@conf_path}"
122
+ def to_s
123
+ "Apache Config #{@conf_path}"
124
+ end
123
125
  end
124
126
  end
data/lib/resources/apt.rb CHANGED
@@ -28,120 +28,122 @@
28
28
 
29
29
  require 'uri'
30
30
 
31
- class AptRepository < Inspec.resource(1)
32
- name 'apt'
33
- desc 'Use the apt InSpec audit resource to verify Apt repositories on the Debian and Ubuntu platforms, and also PPA repositories on the Ubuntu platform.'
34
- example "
35
- describe apt('nginx/stable') do
36
- it { should exist }
37
- it { should be_enabled }
31
+ module Inspec::Resources
32
+ class AptRepository < Inspec.resource(1)
33
+ name 'apt'
34
+ desc 'Use the apt InSpec audit resource to verify Apt repositories on the Debian and Ubuntu platforms, and also PPA repositories on the Ubuntu platform.'
35
+ example "
36
+ describe apt('nginx/stable') do
37
+ it { should exist }
38
+ it { should be_enabled }
39
+ end
40
+ "
41
+
42
+ def initialize(ppa_name)
43
+ @deb_url = nil
44
+ # check if the os is ubuntu or debian
45
+ if inspec.os.debian?
46
+ @deb_url = determine_ppa_url(ppa_name)
47
+ else
48
+ # this resource is only supported on ubuntu and debian
49
+ skip_resource 'The `apt` resource is not supported on your OS yet.'
50
+ end
38
51
  end
39
- "
40
-
41
- def initialize(ppa_name)
42
- @deb_url = nil
43
- # check if the os is ubuntu or debian
44
- if inspec.os.debian?
45
- @deb_url = determine_ppa_url(ppa_name)
46
- else
47
- # this resource is only supported on ubuntu and debian
48
- skip_resource 'The `apt` resource is not supported on your OS yet.'
49
- end
50
- end
51
52
 
52
- def exists?
53
- find_repo.count > 0
54
- end
53
+ def exists?
54
+ find_repo.count > 0
55
+ end
55
56
 
56
- def enabled?
57
- return false if find_repo.count == 0
58
- actives = find_repo.map { |repo| repo[:active] }
59
- actives = actives.uniq
60
- actives.size == 1 && actives[0] = true
61
- end
57
+ def enabled?
58
+ return false if find_repo.count == 0
59
+ actives = find_repo.map { |repo| repo[:active] }
60
+ actives = actives.uniq
61
+ actives.size == 1 && actives[0] = true
62
+ end
62
63
 
63
- def to_s
64
- "Apt Repository #{@deb_url}"
65
- end
64
+ def to_s
65
+ "Apt Repository #{@deb_url}"
66
+ end
66
67
 
67
- private
68
+ private
68
69
 
69
- def find_repo
70
- read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == 'deb' }
71
- end
70
+ def find_repo
71
+ read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == 'deb' }
72
+ end
72
73
 
73
- HTTP_URL_RE = /\A#{URI::DEFAULT_PARSER.make_regexp(%w{http https})}\z/
74
+ HTTP_URL_RE = /\A#{URI::DEFAULT_PARSER.make_regexp(%w{http https})}\z/
74
75
 
75
- # read
76
- def read_debs
77
- return @repo_cache if defined?(@repo_cache)
76
+ # read
77
+ def read_debs
78
+ return @repo_cache if defined?(@repo_cache)
78
79
 
79
- # load all lists
80
- cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
80
+ # load all lists
81
+ cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
81
82
 
82
- # @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
83
- @repo_cache = cmd.stdout.chomp.split("\n").each_with_object([]) do |raw_line, lines|
84
- active = true
83
+ # @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
84
+ @repo_cache = cmd.stdout.chomp.split("\n").each_with_object([]) do |raw_line, lines|
85
+ active = true
85
86
 
86
- # detect if the repo is commented out
87
- line = raw_line.gsub(/^(#\s*)*/, '')
88
- active = false if raw_line != line
87
+ # detect if the repo is commented out
88
+ line = raw_line.gsub(/^(#\s*)*/, '')
89
+ active = false if raw_line != line
89
90
 
90
- # eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
91
- parse_repo = /^\s*(\S+)\s+"?([^ "\t\r\n\f]+)"?\s+(\S+)\s+(.*)$/.match(line)
91
+ # eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
92
+ parse_repo = /^\s*(\S+)\s+"?([^ "\t\r\n\f]+)"?\s+(\S+)\s+(.*)$/.match(line)
92
93
 
93
- # check if we got any result and the second param is an url
94
- next if parse_repo.nil? || !parse_repo[2] =~ HTTP_URL_RE
94
+ # check if we got any result and the second param is an url
95
+ next if parse_repo.nil? || !parse_repo[2] =~ HTTP_URL_RE
95
96
 
96
- # map data
97
- repo = {
98
- type: parse_repo[1],
99
- url: parse_repo[2],
100
- distro: parse_repo[3],
101
- components: parse_repo[4].chomp.split(' '),
102
- active: active,
103
- }
104
- next unless ['deb', 'deb-src'].include? repo[:type]
97
+ # map data
98
+ repo = {
99
+ type: parse_repo[1],
100
+ url: parse_repo[2],
101
+ distro: parse_repo[3],
102
+ components: parse_repo[4].chomp.split(' '),
103
+ active: active,
104
+ }
105
+ next unless ['deb', 'deb-src'].include? repo[:type]
105
106
 
106
- lines.push(repo)
107
+ lines.push(repo)
108
+ end
107
109
  end
108
- end
109
110
 
110
- # resolves ppa urls
111
- # @see http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py
112
- def determine_ppa_url(ppa_url)
113
- # verify if we have the url already, then just return
114
- return ppa_url if ppa_url =~ HTTP_URL_RE
115
- # otherwise start generating the ppa url
111
+ # resolves ppa urls
112
+ # @see http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py
113
+ def determine_ppa_url(ppa_url)
114
+ # verify if we have the url already, then just return
115
+ return ppa_url if ppa_url =~ HTTP_URL_RE
116
+ # otherwise start generating the ppa url
116
117
 
117
- # special care if the name stats with :
118
- ppa_url = ppa_url.split(':')[1] if ppa_url.start_with?('ppa:')
118
+ # special care if the name stats with :
119
+ ppa_url = ppa_url.split(':')[1] if ppa_url.start_with?('ppa:')
119
120
 
120
- # parse ppa owner and repo
121
- ppa_owner, ppa_repo = ppa_url.split('/')
122
- ppa_repo = 'ppa' if ppa_repo.nil?
121
+ # parse ppa owner and repo
122
+ ppa_owner, ppa_repo = ppa_url.split('/')
123
+ ppa_repo = 'ppa' if ppa_repo.nil?
123
124
 
124
- # construct new ppa url and return it
125
- format('http://ppa.launchpad.net/%s/%s/ubuntu', ppa_owner, ppa_repo)
125
+ # construct new ppa url and return it
126
+ format('http://ppa.launchpad.net/%s/%s/ubuntu', ppa_owner, ppa_repo)
127
+ end
126
128
  end
127
- end
128
129
 
129
- # for compatability with serverspec
130
- # this is deprecated syntax and will be removed in future versions
131
- class PpaRepository < AptRepository
132
- name 'ppa'
130
+ # for compatability with serverspec
131
+ # this is deprecated syntax and will be removed in future versions
132
+ class PpaRepository < AptRepository
133
+ name 'ppa'
133
134
 
134
- def exists?
135
- deprecated
136
- super()
137
- end
135
+ def exists?
136
+ deprecated
137
+ super()
138
+ end
138
139
 
139
- def enabled?
140
- deprecated
141
- super()
142
- end
140
+ def enabled?
141
+ deprecated
142
+ super()
143
+ end
143
144
 
144
- def deprecated
145
- warn '[DEPRECATION] `ppa(reponame)` is deprecated. Please use `apt(reponame)` instead.'
145
+ def deprecated
146
+ warn '[DEPRECATION] `ppa(reponame)` is deprecated. Please use `apt(reponame)` instead.'
147
+ end
146
148
  end
147
149
  end