inspec 1.31.0 → 1.45.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +2599 -1
- data/Gemfile +0 -1
- data/README.md +24 -34
- data/Rakefile +0 -31
- data/docs/dsl_inspec.md +10 -0
- data/docs/matchers.md +29 -0
- data/docs/plugin_kitchen_inspec.md +18 -24
- data/docs/profiles.md +101 -81
- data/docs/resources/aide_conf.md.erb +71 -0
- data/docs/resources/apache_conf.md.erb +19 -33
- data/docs/resources/apt.md.erb +22 -36
- data/docs/resources/audit_policy.md.erb +9 -24
- data/docs/resources/auditd.md.erb +78 -0
- data/docs/resources/auditd_conf.md.erb +20 -34
- data/docs/resources/auditd_rules.md.erb +8 -24
- data/docs/resources/bash.md.erb +4 -26
- data/docs/resources/bond.md.erb +25 -40
- data/docs/resources/bridge.md.erb +5 -25
- data/docs/resources/bsd_service.md.erb +5 -25
- data/docs/resources/command.md.erb +35 -50
- data/docs/resources/cpan.md.erb +62 -0
- data/docs/resources/cran.md.erb +54 -0
- data/docs/resources/crontab.md.erb +9 -23
- data/docs/resources/csv.md.erb +12 -27
- data/docs/resources/dh_params.md +1 -0
- data/docs/resources/directory.md.erb +5 -25
- data/docs/resources/docker.md.erb +61 -58
- data/docs/resources/docker_container.md.erb +23 -19
- data/docs/resources/docker_image.md.erb +20 -16
- data/docs/resources/elasticsearch.md.erb +245 -0
- data/docs/resources/etc_fstab.md.erb +120 -0
- data/docs/resources/etc_group.md.erb +29 -45
- data/docs/resources/etc_hosts.md.erb +68 -0
- data/docs/resources/etc_hosts_allow.md.erb +68 -0
- data/docs/resources/etc_hosts_deny.md.erb +68 -0
- data/docs/resources/file.md.erb +227 -216
- data/docs/resources/firewalld.md.erb +104 -0
- data/docs/resources/gem.md.erb +21 -35
- data/docs/resources/group.md.erb +16 -30
- data/docs/resources/grub_conf.md.erb +9 -24
- data/docs/resources/host.md.erb +32 -49
- data/docs/resources/http.md.erb +38 -44
- data/docs/resources/iis_app.md.erb +25 -35
- data/docs/resources/iis_site.md.erb +26 -40
- data/docs/resources/inetd_conf.md.erb +27 -42
- data/docs/resources/ini.md.erb +9 -23
- data/docs/resources/interface.md.erb +5 -25
- data/docs/resources/iptables.md.erb +15 -29
- data/docs/resources/json.md.erb +12 -27
- data/docs/resources/kernel_module.md.erb +47 -61
- data/docs/resources/kernel_parameter.md.erb +15 -29
- data/docs/resources/key_rsa.md.erb +3 -0
- data/docs/resources/launchd_service.md.erb +5 -25
- data/docs/resources/limits_conf.md.erb +15 -29
- data/docs/resources/login_def.md.erb +15 -30
- data/docs/resources/mount.md.erb +18 -33
- data/docs/resources/mssql_session.md.erb +9 -12
- data/docs/resources/mysql_conf.md.erb +28 -32
- data/docs/resources/mysql_session.md.erb +15 -29
- data/docs/resources/nginx.md.erb +78 -0
- data/docs/resources/nginx_conf.md.erb +127 -0
- data/docs/resources/npm.md.erb +19 -35
- data/docs/resources/ntp_conf.md.erb +20 -37
- data/docs/resources/oneget.md.erb +15 -30
- data/docs/resources/oracledb_session.md.erb +9 -11
- data/docs/resources/os.md.erb +29 -43
- data/docs/resources/os_env.md.erb +23 -44
- data/docs/resources/package.md.erb +34 -36
- data/docs/resources/parse_config.md.erb +5 -25
- data/docs/resources/parse_config_file.md.erb +31 -43
- data/docs/resources/{etc_passwd.md.erb → passwd.md.erb} +24 -39
- data/docs/resources/pip.md.erb +20 -35
- data/docs/resources/port.md.erb +43 -57
- data/docs/resources/postgres_conf.md.erb +17 -31
- data/docs/resources/postgres_hba_conf.md.erb +26 -38
- data/docs/resources/postgres_ident_conf.md.erb +25 -37
- data/docs/resources/postgres_session.md.erb +15 -29
- data/docs/resources/powershell.md.erb +27 -42
- data/docs/resources/processes.md.erb +17 -33
- data/docs/resources/rabbitmq_config.md.erb +9 -24
- data/docs/resources/registry_key.md.erb +27 -42
- data/docs/resources/runit_service.md.erb +5 -25
- data/docs/resources/security_policy.md.erb +12 -27
- data/docs/resources/service.md.erb +27 -42
- data/docs/resources/{etc_shadow.md.erb → shadow.md.erb} +41 -47
- data/docs/resources/ssh_config.md.erb +19 -34
- data/docs/resources/sshd_config.md.erb +19 -34
- data/docs/resources/ssl.md.erb +39 -54
- data/docs/resources/sys_info.md.erb +12 -26
- data/docs/resources/systemd_service.md.erb +5 -25
- data/docs/resources/sysv_service.md.erb +5 -25
- data/docs/resources/upstart_service.md.erb +5 -25
- data/docs/resources/user.md.erb +29 -44
- data/docs/resources/users.md.erb +12 -26
- data/docs/resources/vbscript.md.erb +9 -24
- data/docs/resources/virtualization.md.erb +8 -23
- data/docs/resources/windows_feature.md.erb +15 -30
- data/docs/resources/windows_hotfix.md.erb +50 -0
- data/docs/resources/windows_task.md.erb +12 -26
- data/docs/resources/wmi.md.erb +9 -24
- data/docs/resources/x509_certificate.md.erb +4 -0
- data/docs/resources/xinetd_conf.md.erb +65 -80
- data/docs/resources/xml.md.erb +61 -0
- data/docs/resources/yaml.md.erb +12 -27
- data/docs/resources/yum.md.erb +37 -51
- data/docs/resources/zfs_dataset.md.erb +15 -26
- data/docs/resources/zfs_pool.md.erb +9 -20
- data/docs/ruby_usage.md +0 -1
- data/examples/meta-profile/README.md +1 -1
- data/examples/profile-sensitive/README.md +29 -0
- data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -0
- data/examples/profile-sensitive/controls/sensitive.rb +9 -0
- data/examples/profile-sensitive/inspec.yml +8 -0
- data/inspec.gemspec +3 -3
- data/lib/bundles/inspec-artifact/cli.rb +5 -5
- data/lib/bundles/inspec-compliance/README.md +24 -22
- data/lib/bundles/inspec-compliance/api/login.rb +152 -0
- data/lib/bundles/inspec-compliance/api.rb +46 -16
- data/lib/bundles/inspec-compliance/cli.rb +58 -165
- data/lib/bundles/inspec-compliance/target.rb +2 -3
- data/lib/bundles/inspec-habitat/cli.rb +7 -2
- data/lib/bundles/inspec-habitat/profile.rb +44 -20
- data/lib/bundles/inspec-init/templates/profile/README.md +1 -1
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +1 -1
- data/lib/bundles/inspec-supermarket/api.rb +1 -1
- data/lib/inspec/backend.rb +8 -0
- data/lib/inspec/cli.rb +1 -1
- data/lib/inspec/control_eval_context.rb +16 -6
- data/lib/inspec/dependencies/requirement.rb +22 -8
- data/lib/inspec/dependencies/resolver.rb +1 -1
- data/lib/inspec/exceptions.rb +4 -0
- data/lib/inspec/file_provider.rb +38 -9
- data/lib/inspec/metadata.rb +17 -3
- data/lib/inspec/objects/attribute.rb +16 -7
- data/lib/inspec/objects/control.rb +10 -2
- data/lib/inspec/plugins/resource.rb +34 -5
- data/lib/inspec/profile.rb +10 -1
- data/lib/inspec/profile_context.rb +3 -1
- data/lib/inspec/resource.rb +17 -5
- data/lib/inspec/rspec_json_formatter.rb +48 -14
- data/lib/inspec/rule.rb +4 -0
- data/lib/inspec/runner.rb +72 -30
- data/lib/inspec/shell.rb +24 -19
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +40 -0
- data/lib/resources/aide_conf.rb +162 -0
- data/lib/resources/auditd.rb +231 -0
- data/lib/resources/auditd_rules.rb +3 -1
- data/lib/resources/command.rb +1 -1
- data/lib/resources/cpan.rb +60 -0
- data/lib/resources/cran.rb +66 -0
- data/lib/resources/docker.rb +8 -1
- data/lib/resources/docker_container.rb +19 -2
- data/lib/resources/elasticsearch.rb +172 -0
- data/lib/resources/etc_fstab.rb +102 -0
- data/lib/resources/etc_group.rb +1 -1
- data/lib/resources/etc_hosts.rb +81 -0
- data/lib/resources/etc_hosts_allow_deny.rb +122 -0
- data/lib/resources/file.rb +87 -10
- data/lib/resources/firewalld.rb +144 -0
- data/lib/resources/groups.rb +0 -1
- data/lib/resources/host.rb +30 -15
- data/lib/resources/http.rb +178 -22
- data/lib/resources/mssql_session.rb +3 -3
- data/lib/resources/mysql_conf.rb +10 -0
- data/lib/resources/mysql_session.rb +1 -1
- data/lib/resources/nginx.rb +97 -0
- data/lib/resources/nginx_conf.rb +134 -1
- data/lib/resources/oracledb_session.rb +9 -8
- data/lib/resources/os_env.rb +7 -4
- data/lib/resources/package.rb +14 -2
- data/lib/resources/packages.rb +1 -1
- data/lib/resources/pip.rb +28 -20
- data/lib/resources/port.rb +251 -3
- data/lib/resources/postgres.rb +1 -1
- data/lib/resources/postgres_session.rb +1 -1
- data/lib/resources/processes.rb +106 -20
- data/lib/resources/registry_key.rb +11 -2
- data/lib/resources/service.rb +5 -24
- data/lib/resources/ssh_conf.rb +1 -1
- data/lib/resources/ssl.rb +4 -3
- data/lib/resources/toml.rb +2 -2
- data/lib/resources/windows_hotfix.rb +35 -0
- data/lib/resources/xinetd.rb +4 -6
- data/lib/resources/xml.rb +27 -0
- data/lib/source_readers/inspec.rb +3 -3
- data/lib/utils/find_files.rb +2 -1
- data/lib/utils/nginx_parser.rb +10 -1
- data/lib/utils/object_traversal.rb +35 -10
- data/lib/utils/parser.rb +21 -3
- metadata +48 -18
- data/docs/cli.md +0 -392
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Aaron Lippold, lippold@gmail.com
|
|
3
|
+
# author: Rony Xavier, rx294@gmail.com
|
|
4
|
+
|
|
5
|
+
require 'pathname'
|
|
6
|
+
require 'hashie/mash'
|
|
7
|
+
|
|
8
|
+
module Inspec::Resources
|
|
9
|
+
class Nginx < Inspec.resource(1)
|
|
10
|
+
name 'nginx'
|
|
11
|
+
desc 'Use the nginx InSpec audit resource to test information about your NGINX instance.'
|
|
12
|
+
example "
|
|
13
|
+
describe nginx do
|
|
14
|
+
its('conf_path') { should cmp '/etc/nginx/nginx.conf' }
|
|
15
|
+
end
|
|
16
|
+
describe nginx('/etc/sbin/') do
|
|
17
|
+
its('version') { should be >= '1.0.0' }
|
|
18
|
+
end
|
|
19
|
+
describe nginx do
|
|
20
|
+
its('modules') { should include 'my_module' }
|
|
21
|
+
end
|
|
22
|
+
"
|
|
23
|
+
attr_reader :params, :bin_dir
|
|
24
|
+
|
|
25
|
+
def initialize(nginx_path = '/usr/sbin/nginx')
|
|
26
|
+
return skip_resource 'The `nginx` resource is not yet available on your OS.' if inspec.os.windows?
|
|
27
|
+
return skip_resource 'The `nginx` binary not found in the path provided.' unless inspec.command(nginx_path).exist?
|
|
28
|
+
|
|
29
|
+
cmd = inspec.command("#{nginx_path} -V 2>&1")
|
|
30
|
+
if !cmd.exit_status.zero?
|
|
31
|
+
return skip_resource 'Error using the command nginx -V'
|
|
32
|
+
end
|
|
33
|
+
@data = cmd.stdout
|
|
34
|
+
@params = {}
|
|
35
|
+
read_content
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
%w{compiler_info error_log_path http_client_body_temp_path http_fastcgi_temp_path http_log_path http_proxy_temp_path http_scgi_temp_path http_uwsgi_temp_path lock_path modules_path openssl_version prefix sbin_path service support_info version}.each do |property|
|
|
39
|
+
define_method(property.to_sym) do
|
|
40
|
+
@params[property.to_sym]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def openssl_version
|
|
45
|
+
result = @data.scan(/built with OpenSSL\s(\S+)\s(\d+\s\S+\s\d{4})/).flatten
|
|
46
|
+
Hashie::Mash.new({ 'version' => result[0], 'date' => result[1] })
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def compiler_info
|
|
50
|
+
result = @data.scan(/built by (\S+)\s(\S+)\s(\S+)/).flatten
|
|
51
|
+
Hashie::Mash.new({ 'compiler' => result[0], 'version' => result[1], 'date' => result[2] })
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def support_info
|
|
55
|
+
support_info = @data.scan(/(.*\S+) support enabled/).flatten
|
|
56
|
+
support_info.empty? ? nil : support_info.join(' ')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def modules
|
|
60
|
+
@data.scan(/--with-(\S+)_module/).flatten
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_s
|
|
64
|
+
'Nginx Environment'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def read_content
|
|
70
|
+
parse_config
|
|
71
|
+
parse_path
|
|
72
|
+
parse_http_path
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def parse_config
|
|
76
|
+
@params[:prefix] = @data.scan(/--prefix=(\S+)\s/).flatten.first
|
|
77
|
+
@params[:service] = 'nginx'
|
|
78
|
+
@params[:version] = @data.scan(%r{nginx version: nginx\/(\S+)\s}).flatten.first
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_path
|
|
82
|
+
@params[:sbin_path] = @data.scan(/--sbin-path=(\S+)\s/).flatten.first
|
|
83
|
+
@params[:modules_path] = @data.scan(/--modules-path=(\S+)\s/).flatten.first
|
|
84
|
+
@params[:error_log_path] = @data.scan(/--error-log-path=(\S+)\s/).flatten.first
|
|
85
|
+
@params[:http_log_path] = @data.scan(/--http-log-path=(\S+)\s/).flatten.first
|
|
86
|
+
@params[:lock_path] = @data.scan(/--lock-path=(\S+)\s/).flatten.first
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def parse_http_path
|
|
90
|
+
@params[:http_client_body_temp_path] = @data.scan(/--http-client-body-temp-path=(\S+)\s/).flatten.first
|
|
91
|
+
@params[:http_proxy_temp_path] = @data.scan(/--http-proxy-temp-path=(\S+)\s/).flatten.first
|
|
92
|
+
@params[:http_fastcgi_temp_path] = @data.scan(/--http-fastcgi-temp-path=(\S+)\s/).flatten.first
|
|
93
|
+
@params[:http_uwsgi_temp_path] = @data.scan(/--http-uwsgi-temp-path=(\S+)\s/).flatten.first
|
|
94
|
+
@params[:http_scgi_temp_path] = @data.scan(/--http-scgi-temp-path=(\S+)\s/).flatten.first
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/resources/nginx_conf.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
4
|
|
|
5
5
|
require 'utils/nginx_parser'
|
|
6
|
+
require 'utils/find_files'
|
|
7
|
+
require 'forwardable'
|
|
6
8
|
|
|
7
9
|
# STABILITY: Experimental
|
|
8
10
|
# This resouce needs a proper interace to the underlying data, which is currently missing.
|
|
@@ -22,6 +24,10 @@ module Inspec::Resources
|
|
|
22
24
|
describe nginx_conf('/path/to/my/nginx.conf').params ...
|
|
23
25
|
"
|
|
24
26
|
|
|
27
|
+
extend Forwardable
|
|
28
|
+
|
|
29
|
+
include FindFiles
|
|
30
|
+
|
|
25
31
|
attr_reader :contents
|
|
26
32
|
|
|
27
33
|
def initialize(conf_path = nil)
|
|
@@ -37,6 +43,12 @@ module Inspec::Resources
|
|
|
37
43
|
@params = {}
|
|
38
44
|
end
|
|
39
45
|
|
|
46
|
+
def http
|
|
47
|
+
NginxConfHttp.new(params['http'], self)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def_delegators :http, :servers, :locations
|
|
51
|
+
|
|
40
52
|
def to_s
|
|
41
53
|
"nginx_conf #{@conf_path}"
|
|
42
54
|
end
|
|
@@ -84,12 +96,133 @@ module Inspec::Resources
|
|
|
84
96
|
if data.key?('include')
|
|
85
97
|
data.delete('include').flatten
|
|
86
98
|
.map { |x| File.expand_path(x, rel_path) }
|
|
99
|
+
.map { |x| find_files(x) }.flatten
|
|
87
100
|
.map { |path| parse_nginx(path) }
|
|
88
|
-
.
|
|
101
|
+
.each { |conf| merge_config!(data, conf) }
|
|
89
102
|
end
|
|
90
103
|
|
|
91
104
|
# Walk through the remaining hash fields to find more references
|
|
92
105
|
Hash[data.map { |k, v| [k, resolve_references(v, rel_path)] }]
|
|
93
106
|
end
|
|
107
|
+
|
|
108
|
+
# Deep merge fields from NginxConfig.parse.
|
|
109
|
+
# A regular merge would overwrite values so a deep merge is needed.
|
|
110
|
+
# @param data [Hash] data structure from NginxConfig.parse
|
|
111
|
+
# @param conf [Hash] data structure to be deep merged into data
|
|
112
|
+
# @return [Hash] data structure with conf and data deep merged
|
|
113
|
+
def merge_config!(data, conf)
|
|
114
|
+
# Catch edge-cases
|
|
115
|
+
return if data.nil? || conf.nil?
|
|
116
|
+
# Step through all conf items and create combined return value
|
|
117
|
+
data.merge!(conf) do |_, v1, v2|
|
|
118
|
+
if v1.is_a?(Array) && v2.is_a?(Array)
|
|
119
|
+
# If both the data field and the conf field are arrays, then combine them
|
|
120
|
+
v1 + v2
|
|
121
|
+
elsif v1.is_a?(Hash) && v2.is_a?(Hash)
|
|
122
|
+
# If both the data field and the conf field are maps, then deep merge them
|
|
123
|
+
merge_config!(v1, v2)
|
|
124
|
+
else
|
|
125
|
+
# All other cases, just use the new value (regular merge behavior)
|
|
126
|
+
v2
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
class NginxConfHttp
|
|
133
|
+
attr_reader :entries
|
|
134
|
+
def initialize(params, parent)
|
|
135
|
+
@parent = parent
|
|
136
|
+
@entries = (params || []).map { |x| NginxConfHttpEntry.new(x, parent) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def servers
|
|
140
|
+
@entries.map(&:servers).flatten
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def locations
|
|
144
|
+
servers.map(&:locations).flatten
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def to_s
|
|
148
|
+
@parent.to_s + ', http entries'
|
|
149
|
+
end
|
|
150
|
+
alias inspect to_s
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class NginxConfHttpEntry
|
|
154
|
+
attr_reader :params, :parent
|
|
155
|
+
def initialize(params, parent)
|
|
156
|
+
@params = params || {}
|
|
157
|
+
@parent = parent
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
filter = FilterTable.create
|
|
161
|
+
filter.add_accessor(:where)
|
|
162
|
+
.add(:servers, field: 'server')
|
|
163
|
+
.connect(self, :server_table)
|
|
164
|
+
|
|
165
|
+
def locations
|
|
166
|
+
servers.map(&:locations).flatten
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def to_s
|
|
170
|
+
@parent.to_s + ', http entry'
|
|
171
|
+
end
|
|
172
|
+
alias inspect to_s
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
|
|
176
|
+
def server_table
|
|
177
|
+
@server_table ||= (params['server'] || []).map { |x| { 'server' => NginxConfServer.new(x, self) } }
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class NginxConfServer
|
|
182
|
+
attr_reader :params, :parent
|
|
183
|
+
def initialize(params, parent)
|
|
184
|
+
@parent = parent
|
|
185
|
+
@params = params || {}
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
filter = FilterTable.create
|
|
189
|
+
filter.add_accessor(:where)
|
|
190
|
+
.add(:locations, field: 'location')
|
|
191
|
+
.connect(self, :location_table)
|
|
192
|
+
|
|
193
|
+
def to_s
|
|
194
|
+
server = ''
|
|
195
|
+
name = Array(params['server_name']).flatten.first
|
|
196
|
+
unless name.nil?
|
|
197
|
+
server += name
|
|
198
|
+
listen = Array(params['listen']).flatten.first
|
|
199
|
+
server += ":#{listen}" unless listen.nil?
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# go two levels up: 1. to the http entry and 2. to the root nginx conf
|
|
203
|
+
@parent.parent.to_s + ", server #{server}"
|
|
204
|
+
end
|
|
205
|
+
alias inspect to_s
|
|
206
|
+
|
|
207
|
+
private
|
|
208
|
+
|
|
209
|
+
def location_table
|
|
210
|
+
@location_table ||= (params['location'] || []).map { |x| { 'location' => NginxConfLocation.new(x, self) } }
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
class NginxConfLocation
|
|
215
|
+
attr_reader :params, :parent
|
|
216
|
+
def initialize(params, parent)
|
|
217
|
+
@parent = parent
|
|
218
|
+
@params = params || {}
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def to_s
|
|
222
|
+
location = Array(params['_']).join(' ')
|
|
223
|
+
# go three levels up: 1. to the server entry, 2. http entry and 3. to the root nginx conf
|
|
224
|
+
@parent.parent.parent.to_s + ", location #{location.inspect}"
|
|
225
|
+
end
|
|
226
|
+
alias inspect to_s
|
|
94
227
|
end
|
|
95
228
|
end
|
|
@@ -49,19 +49,20 @@ module Inspec::Resources
|
|
|
49
49
|
escaped_query = escaped_query.gsub('$', '\\$')
|
|
50
50
|
|
|
51
51
|
p = nil
|
|
52
|
-
#
|
|
53
|
-
if inspec.command(@
|
|
54
|
-
bin = @sqlplus_bin
|
|
55
|
-
opts = "SET MARKUP HTML ON\nSET FEEDBACK OFF"
|
|
56
|
-
p = :parse_html_result
|
|
57
|
-
elsif inspec.command(@sqlcl_bin).exist?
|
|
52
|
+
# use sqlplus if sqlcl is not available
|
|
53
|
+
if inspec.command(@sqlcl_bin).exist?
|
|
58
54
|
bin = @sqlcl_bin
|
|
59
55
|
opts = "set sqlformat csv\nSET FEEDBACK OFF"
|
|
60
56
|
p = :parse_csv_result
|
|
57
|
+
else
|
|
58
|
+
bin = @sqlplus_bin
|
|
59
|
+
opts = "SET MARKUP HTML ON\nSET FEEDBACK OFF"
|
|
60
|
+
p = :parse_html_result
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
query = verify_query(escaped_query)
|
|
64
|
+
query += ';' unless query.end_with?(';')
|
|
65
|
+
command = %{echo "#{opts}\n#{query}\nEXIT" | #{bin} "#{@user}"/"#{@password}"@#{@host}:#{@port}/#{@service}}
|
|
65
66
|
cmd = inspec.command(command)
|
|
66
67
|
|
|
67
68
|
out = cmd.stdout + "\n" + cmd.stderr
|
data/lib/resources/os_env.rb
CHANGED
|
@@ -25,8 +25,6 @@ module Inspec::Resources
|
|
|
25
25
|
attr_reader :content
|
|
26
26
|
def initialize(env = nil)
|
|
27
27
|
@osenv = env
|
|
28
|
-
@content = nil
|
|
29
|
-
@content = value_for(env) unless env.nil?
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
def split
|
|
@@ -35,7 +33,12 @@ module Inspec::Resources
|
|
|
35
33
|
path_separator = inspec.os.windows? ? ';' : ':'
|
|
36
34
|
# -1 is required to catch cases like dir1::dir2:
|
|
37
35
|
# where we have a trailing :
|
|
38
|
-
|
|
36
|
+
content.nil? ? [] : content.split(path_separator, -1)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def content
|
|
40
|
+
return @content if defined?(@content)
|
|
41
|
+
@content = value_for(@osenv) unless @osenv.nil?
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
def to_s
|
|
@@ -58,7 +61,7 @@ module Inspec::Resources
|
|
|
58
61
|
out = inspec.command(command)
|
|
59
62
|
|
|
60
63
|
unless out.exit_status == 0
|
|
61
|
-
skip_resource "Can't read environment variables on #{os
|
|
64
|
+
skip_resource "Can't read environment variables on #{inspec.os.name}. "\
|
|
62
65
|
"Tried `#{command}` which returned #{out.exit_status}"
|
|
63
66
|
end
|
|
64
67
|
|
data/lib/resources/package.rb
CHANGED
|
@@ -15,6 +15,7 @@ module Inspec::Resources
|
|
|
15
15
|
example "
|
|
16
16
|
describe package('nginx') do
|
|
17
17
|
it { should be_installed }
|
|
18
|
+
it { should_not be_held } # for dpkg platforms that support holding a version from being upgraded
|
|
18
19
|
its('version') { should eq 1.9.5 }
|
|
19
20
|
end
|
|
20
21
|
"
|
|
@@ -56,6 +57,13 @@ module Inspec::Resources
|
|
|
56
57
|
info[:installed] == true
|
|
57
58
|
end
|
|
58
59
|
|
|
60
|
+
# returns true it the package is held (if the OS supports it)
|
|
61
|
+
def held?(_provider = nil, _version = nil)
|
|
62
|
+
return false if info.nil?
|
|
63
|
+
return false unless info.key?(:held)
|
|
64
|
+
info[:held] == true
|
|
65
|
+
end
|
|
66
|
+
|
|
59
67
|
# returns the package description
|
|
60
68
|
def info
|
|
61
69
|
return @cache if !@cache.nil?
|
|
@@ -107,11 +115,14 @@ module Inspec::Resources
|
|
|
107
115
|
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
108
116
|
multiple_values: false,
|
|
109
117
|
).params
|
|
118
|
+
# If the package is installed, Status is "install ok installed"
|
|
119
|
+
# If the package is installed and marked hold, Status is "hold ok installed"
|
|
110
120
|
# If the package is removed and not purged, Status is "deinstall ok config-files" with exit_status 0
|
|
111
121
|
# If the package is purged cmd fails with non-zero exit status
|
|
112
122
|
{
|
|
113
123
|
name: params['Package'],
|
|
114
|
-
installed: params['Status'].split(' ')
|
|
124
|
+
installed: params['Status'].split(' ')[2] == 'installed',
|
|
125
|
+
held: params['Status'].split(' ')[0] == 'hold',
|
|
115
126
|
version: params['Version'],
|
|
116
127
|
type: 'deb',
|
|
117
128
|
}
|
|
@@ -182,7 +193,8 @@ module Inspec::Resources
|
|
|
182
193
|
# MacOS / Darwin implementation
|
|
183
194
|
class Brew < PkgManagement
|
|
184
195
|
def info(package_name)
|
|
185
|
-
|
|
196
|
+
brew_path = inspec.command('brew').exist? ? 'brew' : '/usr/local/bin/brew'
|
|
197
|
+
cmd = inspec.command("#{brew_path} info --json=v1 #{package_name}")
|
|
186
198
|
return nil if cmd.exit_status.to_i != 0
|
|
187
199
|
# parse data
|
|
188
200
|
pkg = JSON.parse(cmd.stdout)[0]
|
data/lib/resources/packages.rb
CHANGED
|
@@ -63,7 +63,7 @@ module Inspec::Resources
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def filtered_packages
|
|
66
|
-
warn "The packages resource is not yet supported on OS #{inspec.os.name}" if resource_skipped
|
|
66
|
+
warn "The packages resource is not yet supported on OS #{inspec.os.name}" if resource_skipped?
|
|
67
67
|
@list
|
|
68
68
|
end
|
|
69
69
|
end
|
data/lib/resources/pip.rb
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
# it { should be_installed }
|
|
8
8
|
# end
|
|
9
9
|
#
|
|
10
|
+
|
|
10
11
|
module Inspec::Resources
|
|
11
12
|
class PipPackage < Inspec.resource(1)
|
|
12
13
|
name 'pip'
|
|
@@ -15,10 +16,17 @@ module Inspec::Resources
|
|
|
15
16
|
describe pip('Jinja2') do
|
|
16
17
|
it { should be_installed }
|
|
17
18
|
end
|
|
19
|
+
|
|
20
|
+
describe pip('django', '/path/to/virtualenv/bin/pip') do
|
|
21
|
+
it { should be_installed }
|
|
22
|
+
its('version') { should eq('1.11.4')}
|
|
23
|
+
end
|
|
18
24
|
"
|
|
19
25
|
|
|
20
|
-
def initialize(package_name)
|
|
26
|
+
def initialize(package_name, pip_path = nil)
|
|
21
27
|
@package_name = package_name
|
|
28
|
+
@pip_cmd = pip_path || default_pip_path
|
|
29
|
+
return skip_resource 'pip not found' unless inspec.command(@pip_cmd).exist?
|
|
22
30
|
end
|
|
23
31
|
|
|
24
32
|
def info
|
|
@@ -26,7 +34,7 @@ module Inspec::Resources
|
|
|
26
34
|
|
|
27
35
|
@info = {}
|
|
28
36
|
@info[:type] = 'pip'
|
|
29
|
-
cmd = inspec.command("#{pip_cmd} show #{@package_name}")
|
|
37
|
+
cmd = inspec.command("#{@pip_cmd} show #{@package_name}")
|
|
30
38
|
return @info if cmd.exit_status != 0
|
|
31
39
|
|
|
32
40
|
params = SimpleConfig.new(
|
|
@@ -54,28 +62,28 @@ module Inspec::Resources
|
|
|
54
62
|
|
|
55
63
|
private
|
|
56
64
|
|
|
57
|
-
def
|
|
65
|
+
def default_pip_path
|
|
66
|
+
return 'pip' unless inspec.os.windows?
|
|
67
|
+
|
|
58
68
|
# Pip is not on the default path for Windows, therefore we do some logic
|
|
59
69
|
# to find the binary on Windows
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
pipdir.pop
|
|
72
|
-
pipcmd = pipdir.push('Scripts').push('pip.exe').join('/')
|
|
73
|
-
end
|
|
74
|
-
rescue JSON::ParserError => _e
|
|
75
|
-
return nil
|
|
70
|
+
cmd = inspec.command('New-Object -Type PSObject | Add-Member -MemberType NoteProperty -Name Pip -Value (Invoke-Command -ScriptBlock {where.exe pip}) -PassThru | Add-Member -MemberType NoteProperty -Name Python -Value (Invoke-Command -ScriptBlock {where.exe python}) -PassThru | ConvertTo-Json')
|
|
71
|
+
begin
|
|
72
|
+
paths = JSON.parse(cmd.stdout)
|
|
73
|
+
# use pip if it on system path
|
|
74
|
+
pipcmd = paths['Pip']
|
|
75
|
+
# calculate path on windows
|
|
76
|
+
if defined?(paths['Python']) && pipcmd.nil?
|
|
77
|
+
pipdir = paths['Python'].split('\\')
|
|
78
|
+
# remove python.exe
|
|
79
|
+
pipdir.pop
|
|
80
|
+
pipcmd = pipdir.push('Scripts').push('pip.exe').join('/')
|
|
76
81
|
end
|
|
82
|
+
rescue JSON::ParserError => _e
|
|
83
|
+
return nil
|
|
77
84
|
end
|
|
78
|
-
|
|
85
|
+
|
|
86
|
+
pipcmd
|
|
79
87
|
end
|
|
80
88
|
end
|
|
81
89
|
end
|