inspec 2.3.5 → 2.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -8
  3. data/Rakefile +1 -2
  4. data/lib/bundles/inspec-compliance/api.rb +3 -353
  5. data/lib/bundles/inspec-compliance/configuration.rb +3 -102
  6. data/lib/bundles/inspec-compliance/http.rb +3 -115
  7. data/lib/bundles/inspec-compliance/support.rb +3 -35
  8. data/lib/bundles/inspec-compliance/target.rb +3 -142
  9. data/lib/inspec/base_cli.rb +4 -1
  10. data/lib/inspec/cli.rb +1 -1
  11. data/lib/inspec/control_eval_context.rb +2 -2
  12. data/lib/inspec/version.rb +1 -1
  13. data/lib/matchers/matchers.rb +3 -3
  14. data/lib/{bundles → plugins}/inspec-compliance/README.md +0 -0
  15. data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +12 -0
  16. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +358 -0
  17. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +192 -0
  18. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +266 -0
  19. data/lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb +103 -0
  20. data/lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb +116 -0
  21. data/lib/{bundles → plugins/inspec-compliance/lib}/inspec-compliance/images/cc-token.png +0 -0
  22. data/lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb +36 -0
  23. data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +143 -0
  24. data/lib/plugins/inspec-compliance/test/functional/inspec_compliance_test.rb +43 -0
  25. data/lib/{bundles → plugins}/inspec-compliance/test/integration/default/cli.rb +0 -0
  26. data/lib/plugins/inspec-compliance/test/unit/api/login_test.rb +190 -0
  27. data/lib/plugins/inspec-compliance/test/unit/api_test.rb +385 -0
  28. data/lib/plugins/inspec-compliance/test/unit/target_test.rb +155 -0
  29. data/lib/resources/processes.rb +19 -3
  30. metadata +17 -10
  31. data/lib/bundles/inspec-compliance.rb +0 -16
  32. data/lib/bundles/inspec-compliance/.kitchen.yml +0 -20
  33. data/lib/bundles/inspec-compliance/api/login.rb +0 -193
  34. data/lib/bundles/inspec-compliance/bootstrap.sh +0 -41
  35. data/lib/bundles/inspec-compliance/cli.rb +0 -276
@@ -0,0 +1,155 @@
1
+ require 'minitest/autorun'
2
+ require 'mocha/setup'
3
+ require_relative '../../lib/inspec-compliance/api.rb'
4
+
5
+ describe InspecPlugins::Compliance::Fetcher do
6
+ let(:config) { { 'server' => 'myserver' } }
7
+
8
+ describe 'the check_compliance_token method' do
9
+ let(:fetcher) { fetcher = InspecPlugins::Compliance::Fetcher.new('a/bad/url', config) }
10
+
11
+ it 'returns without error if token is set' do
12
+ config['token'] = 'my-token'
13
+ fetcher.class.check_compliance_token('http://test.com', config)
14
+ end
15
+
16
+ it 'returns an error when token is not set' do
17
+ ex = assert_raises(Inspec::FetcherFailure) { fetcher.class.check_compliance_token('http://test.com', config) }
18
+ ex.message.must_include "Cannot fetch http://test.com because your compliance token has not been\nconfigured."
19
+ end
20
+ end
21
+
22
+ describe 'when the server is an automate2 server' do
23
+ before { InspecPlugins::Compliance::API.expects(:is_automate2_server?).with(config).returns(true) }
24
+
25
+ it 'returns the correct owner and profile name' do
26
+ config['profile'] = ['admin', 'ssh-baseline', nil]
27
+ fetcher = InspecPlugins::Compliance::Fetcher.new('myserver/profile', config)
28
+ fetcher.send(:compliance_profile_name).must_equal 'admin/ssh-baseline'
29
+ end
30
+ end
31
+
32
+ describe 'when the server is an automate server pre-0.8.0' do
33
+ before { InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(true) }
34
+
35
+ it 'returns the correct profile name when the url is correct' do
36
+ fetcher = InspecPlugins::Compliance::Fetcher.new('myserver/myowner/myprofile/tar', config)
37
+ fetcher.send(:compliance_profile_name).must_equal 'myowner/myprofile'
38
+ end
39
+
40
+ it 'raises an exception if the url is malformed' do
41
+ fetcher = InspecPlugins::Compliance::Fetcher.new('a/bad/url', config)
42
+ proc { fetcher.send(:compliance_profile_name) }.must_raise RuntimeError
43
+ end
44
+ end
45
+
46
+ describe 'when the server is an automate server 0.8.0-or-later' do
47
+ before do
48
+ InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(false)
49
+ InspecPlugins::Compliance::API.expects(:is_automate_server_080_and_later?).with(config).returns(true)
50
+ end
51
+
52
+ it 'returns the correct profile name when the url is correct' do
53
+ fetcher = InspecPlugins::Compliance::Fetcher.new('myserver/profiles/myowner/myprofile/tar', config)
54
+ fetcher.send(:compliance_profile_name).must_equal 'myowner/myprofile'
55
+ end
56
+
57
+ it 'raises an exception if the url is malformed' do
58
+ fetcher = InspecPlugins::Compliance::Fetcher.new('a/bad/url', config)
59
+ proc { fetcher.send(:compliance_profile_name) }.must_raise RuntimeError
60
+ end
61
+ end
62
+
63
+ describe 'when the server is not an automate server (likely a compliance server)' do
64
+ before do
65
+ InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(false)
66
+ InspecPlugins::Compliance::API.expects(:is_automate_server_080_and_later?).with(config).returns(false)
67
+ end
68
+
69
+ it 'returns the correct profile name when the url is correct' do
70
+ fetcher = InspecPlugins::Compliance::Fetcher.new('myserver/owners/myowner/compliance/myprofile/tar', config)
71
+ fetcher.send(:compliance_profile_name).must_equal 'myowner/myprofile'
72
+ end
73
+
74
+ it 'raises an exception if the url is malformed' do
75
+ fetcher = InspecPlugins::Compliance::Fetcher.new('a/bad/url', config)
76
+ proc { fetcher.send(:compliance_profile_name) }.must_raise RuntimeError
77
+ end
78
+ end
79
+
80
+ describe 'when the server calls an automate profile' do
81
+ let(:profiles_result) do
82
+ [{ 'name'=>'ssh-baseline',
83
+ 'title'=>'InSpec Profile',
84
+ 'maintainer'=>'The Authors',
85
+ 'copyright'=>'The Authors',
86
+ 'copyright_email'=>'you@example.com',
87
+ 'license'=>'Apache-2.0',
88
+ 'summary'=>'An InSpec Compliance Profile',
89
+ 'version'=>'0.1.1',
90
+ 'owner'=>'admin',
91
+ 'supports'=>[],
92
+ 'depends'=>[],
93
+ 'sha256'=>'132j1kjdasfasdoaefaewo12312',
94
+ 'groups'=>[],
95
+ 'controls'=>[],
96
+ 'attributes'=>[],
97
+ 'latest_version'=>'' }]
98
+ end
99
+ before do
100
+ InspecPlugins::Compliance::Configuration.expects(:new).returns({ 'token' => '123abc', 'server' => 'https://a2.instance.com' })
101
+ end
102
+
103
+ it 'returns the correct profile name when parsing url' do
104
+ InspecPlugins::Compliance::API.stubs(:profiles).returns(['success', profiles_result])
105
+ fetcher = InspecPlugins::Compliance::Fetcher.resolve('compliance://admin/ssh-baseline')
106
+ assert = ['admin', 'ssh-baseline', nil]
107
+ fetcher.instance_variable_get(:"@config")['profile'].must_equal assert
108
+ end
109
+
110
+ it 'returns the correct profile name when parsing compliance hash' do
111
+ InspecPlugins::Compliance::API.stubs(:profiles).returns(['success', profiles_result])
112
+ hash = {
113
+ target: 'https://a2.instance.com/api/v0/compliance/tar',
114
+ compliance: 'admin/ssh-baseline',
115
+ sha256: '132j1kjdasfasdoaefaewo12312',
116
+ }
117
+ fetcher = InspecPlugins::Compliance::Fetcher.resolve(hash)
118
+ assert = ['admin', 'ssh-baseline', nil]
119
+ fetcher.instance_variable_get(:"@config")['profile'].must_equal assert
120
+ end
121
+ end
122
+
123
+ describe 'when the server provides a sha256 in the profiles_result' do
124
+ let(:profiles_result) do
125
+ [{ 'name'=>'ssh-baseline',
126
+ 'title'=>'InSpec Profile',
127
+ 'maintainer'=>'The Authors',
128
+ 'copyright'=>'The Authors',
129
+ 'copyright_email'=>'you@example.com',
130
+ 'license'=>'Apache-2.0',
131
+ 'summary'=>'An InSpec Compliance Profile',
132
+ 'version'=>'0.1.1',
133
+ 'owner'=>'admin',
134
+ 'supports'=>[],
135
+ 'depends'=>[],
136
+ 'sha256'=>'132j1kjdasfasdoaefaewo12312',
137
+ 'groups'=>[],
138
+ 'controls'=>[],
139
+ 'attributes'=>[],
140
+ 'latest_version'=>'' }]
141
+ end
142
+
143
+ before do
144
+ InspecPlugins::Compliance::Configuration.expects(:new).returns({ 'token' => '123abc', 'server' => 'https://a2.instance.com' })
145
+ end
146
+
147
+ it 'contains the upstream_sha256' do
148
+ InspecPlugins::Compliance::API.stubs(:profiles).returns(['success', profiles_result])
149
+ prof = profiles_result[0]
150
+ target = "compliance://#{prof['owner']}/#{prof['name']}"
151
+ fetcher = InspecPlugins::Compliance::Fetcher.resolve(target)
152
+ fetcher.upstream_sha256.must_equal prof['sha256']
153
+ end
154
+ end
155
+ end
@@ -126,7 +126,7 @@ module Inspec::Resources
126
126
  def ps_configuration_for_linux
127
127
  if busybox_ps?
128
128
  command = 'ps -o pid,vsz,rss,tty,stat,time,ruser,args'
129
- regex = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/
129
+ regex = /^\s*(\d+)\s+(\d+(?:\.\d+)?[gm]?)\s+(\d+(?:\.\d+)?[gm]?)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/
130
130
  field_map = {
131
131
  pid: 1,
132
132
  vsz: 2,
@@ -163,6 +163,18 @@ module Inspec::Resources
163
163
  @busybox_ps ||= inspec.command('ps --help').stderr.include?('BusyBox')
164
164
  end
165
165
 
166
+ def convert_to_kilobytes(param)
167
+ return param.to_i unless param.is_a?(String)
168
+
169
+ if param.end_with?('g')
170
+ (param[0..-2].to_f * 1024 * 1024).to_i
171
+ elsif param.end_with?('m')
172
+ (param[0..-2].to_f * 1024).to_i
173
+ else
174
+ param.to_i
175
+ end
176
+ end
177
+
166
178
  def build_process_list(command, regex, field_map)
167
179
  cmd = inspec.command(command)
168
180
  all = cmd.stdout.split("\n")[1..-1]
@@ -187,8 +199,12 @@ module Inspec::Resources
187
199
  end
188
200
 
189
201
  # ensure pid, vsz, and rss are integers for backward compatibility
190
- [:pid, :vsz, :rss].each do |int_param|
191
- process_data[int_param] = process_data[int_param].to_i if process_data.key?(int_param)
202
+ process_data[:pid] = process_data[:pid].to_i if process_data.key?(:pid)
203
+
204
+ # some ps variants (*cough* busybox) display vsz and rss as human readable MB or GB
205
+ [:vsz, :rss].each do |param|
206
+ next unless process_data.key?(param)
207
+ process_data[param] = convert_to_kilobytes(process_data[param])
192
208
  end
193
209
 
194
210
  # strip any newlines off the command
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.5
4
+ version: 2.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-28 00:00:00.000000000 Z
11
+ date: 2018-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train
@@ -587,19 +587,11 @@ files:
587
587
  - examples/profile/libraries/gordon_config.rb
588
588
  - inspec.gemspec
589
589
  - lib/bundles/README.md
590
- - lib/bundles/inspec-compliance.rb
591
- - lib/bundles/inspec-compliance/.kitchen.yml
592
- - lib/bundles/inspec-compliance/README.md
593
590
  - lib/bundles/inspec-compliance/api.rb
594
- - lib/bundles/inspec-compliance/api/login.rb
595
- - lib/bundles/inspec-compliance/bootstrap.sh
596
- - lib/bundles/inspec-compliance/cli.rb
597
591
  - lib/bundles/inspec-compliance/configuration.rb
598
592
  - lib/bundles/inspec-compliance/http.rb
599
- - lib/bundles/inspec-compliance/images/cc-token.png
600
593
  - lib/bundles/inspec-compliance/support.rb
601
594
  - lib/bundles/inspec-compliance/target.rb
602
- - lib/bundles/inspec-compliance/test/integration/default/cli.rb
603
595
  - lib/bundles/inspec-supermarket.rb
604
596
  - lib/bundles/inspec-supermarket/README.md
605
597
  - lib/bundles/inspec-supermarket/api.rb
@@ -707,6 +699,21 @@ files:
707
699
  - lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb
708
700
  - lib/plugins/inspec-artifact/lib/inspec-artifact/cli.rb
709
701
  - lib/plugins/inspec-artifact/test/functional/inspec_artifact_test.rb
702
+ - lib/plugins/inspec-compliance/README.md
703
+ - lib/plugins/inspec-compliance/lib/inspec-compliance.rb
704
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb
705
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb
706
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb
707
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb
708
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb
709
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/images/cc-token.png
710
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb
711
+ - lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb
712
+ - lib/plugins/inspec-compliance/test/functional/inspec_compliance_test.rb
713
+ - lib/plugins/inspec-compliance/test/integration/default/cli.rb
714
+ - lib/plugins/inspec-compliance/test/unit/api/login_test.rb
715
+ - lib/plugins/inspec-compliance/test/unit/api_test.rb
716
+ - lib/plugins/inspec-compliance/test/unit/target_test.rb
710
717
  - lib/plugins/inspec-habitat/lib/inspec-habitat.rb
711
718
  - lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb
712
719
  - lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb
@@ -1,16 +0,0 @@
1
- # encoding: utf-8
2
- # author: Christoph Hartmann
3
- # author: Dominik Richter
4
-
5
- libdir = File.dirname(__FILE__)
6
- $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
7
-
8
- module Compliance
9
- autoload :Configuration, 'inspec-compliance/configuration'
10
- autoload :HTTP, 'inspec-compliance/http'
11
- autoload :Support, 'inspec-compliance/support'
12
- autoload :API, 'inspec-compliance/api'
13
- end
14
-
15
- require 'inspec-compliance/cli'
16
- require 'inspec-compliance/target'
@@ -1,20 +0,0 @@
1
- ---
2
- driver:
3
- name: vagrant
4
- synced_folders:
5
- - ['../../../', '/inspec']
6
- network:
7
- - ['private_network', {ip: '192.168.251.2'}]
8
-
9
- provisioner:
10
- name: shell
11
-
12
- verifier:
13
- name: inspec
14
-
15
- platforms:
16
- - name: ubuntu-14.04
17
- suites:
18
- - name: default
19
- run_list:
20
- attributes:
@@ -1,193 +0,0 @@
1
- # encoding: utf-8
2
- # author: Christoph Hartmann
3
- # author: Dominik Ricter
4
- # author: Jerry Aldrich
5
-
6
- module Compliance
7
- class API
8
- module Login
9
- class CannotDetermineServerType < StandardError; end
10
-
11
- def login(options)
12
- raise ArgumentError, 'Please specify a server using `inspec compliance login https://SERVER`' unless options['server']
13
-
14
- options['server'] = URI("https://#{options['server']}").to_s if URI(options['server']).scheme.nil?
15
-
16
- options['server_type'] = Compliance::API.determine_server_type(options['server'], options['insecure'])
17
-
18
- case options['server_type']
19
- when :automate2
20
- Login::Automate2Server.login(options)
21
- when :automate
22
- Login::AutomateServer.login(options)
23
- when :compliance
24
- Login::ComplianceServer.login(options)
25
- else
26
- raise CannotDetermineServerType, "Unable to determine if #{options['server']} is a Chef Automate or Chef Compliance server"
27
- end
28
- end
29
-
30
- module Automate2Server
31
- def self.login(options)
32
- verify_thor_options(options)
33
-
34
- options['url'] = options['server'] + '/api/v0'
35
- token = options['dctoken'] || options['token']
36
- store_access_token(options, token)
37
- end
38
-
39
- def self.store_access_token(options, token)
40
- config = Compliance::Configuration.new
41
- config.clean
42
-
43
- config['automate'] = {}
44
- config['automate']['ent'] = 'automate'
45
- config['automate']['token_type'] = 'dctoken'
46
- config['server'] = options['url']
47
- config['user'] = options['user']
48
- config['owner'] = options['user']
49
- config['insecure'] = options['insecure'] || false
50
- config['server_type'] = options['server_type'].to_s
51
- config['token'] = token
52
- config['version'] = '0'
53
-
54
- config.store
55
- config
56
- end
57
-
58
- def self.verify_thor_options(o)
59
- error_msg = []
60
-
61
- error_msg.push('Please specify a user using `--user=\'USER\'`') if o['user'].nil?
62
-
63
- if o['token'].nil? && o['dctoken'].nil?
64
- error_msg.push('Please specify a token using `--token=\'APITOKEN\'`')
65
- end
66
-
67
- raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
68
- end
69
- end
70
-
71
- module AutomateServer
72
- def self.login(options)
73
- verify_thor_options(options)
74
-
75
- options['url'] = options['server'] + '/compliance'
76
- token = options['dctoken'] || options['token']
77
- store_access_token(options, token)
78
- end
79
-
80
- def self.store_access_token(options, token)
81
- token_type = if options['token']
82
- 'usertoken'
83
- else
84
- 'dctoken'
85
- end
86
-
87
- config = Compliance::Configuration.new
88
-
89
- config.clean
90
-
91
- config['automate'] = {}
92
- config['automate']['ent'] = options['ent']
93
- config['automate']['token_type'] = token_type
94
- config['server'] = options['url']
95
- config['user'] = options['user']
96
- config['insecure'] = options['insecure'] || false
97
- config['server_type'] = options['server_type'].to_s
98
- config['token'] = token
99
- config['version'] = Compliance::API.version(config)
100
-
101
- config.store
102
- config
103
- end
104
-
105
- # Automate login requires `--ent`, `--user`, and either `--token` or `--dctoken`
106
- def self.verify_thor_options(o)
107
- error_msg = []
108
-
109
- error_msg.push('Please specify a user using `--user=\'USER\'`') if o['user'].nil?
110
- error_msg.push('Please specify an enterprise using `--ent=\'automate\'`') if o['ent'].nil?
111
-
112
- if o['token'].nil? && o['dctoken'].nil?
113
- error_msg.push('Please specify a token using `--token=\'AUTOMATE_TOKEN\'` or `--dctoken=\'DATA_COLLECTOR_TOKEN\'`')
114
- end
115
-
116
- raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
117
- end
118
- end
119
-
120
- module ComplianceServer
121
- def self.login(options)
122
- compliance_verify_thor_options(options)
123
-
124
- options['url'] = options['server'] + '/api'
125
-
126
- if options['user'] && options['token']
127
- compliance_store_access_token(options, options['token'])
128
- elsif options['user'] && options['password']
129
- compliance_login_user_pass(options)
130
- elsif options['refresh_token']
131
- compliance_login_refresh_token(options)
132
- end
133
- end
134
-
135
- def self.compliance_login_user_pass(options)
136
- success, msg, token = Compliance::API.get_token_via_password(
137
- options['url'],
138
- options['user'],
139
- options['password'],
140
- options['insecure'],
141
- )
142
-
143
- raise msg unless success
144
- compliance_store_access_token(options, token)
145
- end
146
-
147
- def self.compliance_login_refresh_token(options)
148
- success, msg, token = Compliance::API.get_token_via_refresh_token(
149
- options['url'],
150
- options['refresh_token'],
151
- options['insecure'],
152
- )
153
-
154
- raise msg unless success
155
- compliance_store_access_token(options, token)
156
- end
157
-
158
- def self.compliance_store_access_token(options, token)
159
- config = Compliance::Configuration.new
160
- config.clean
161
-
162
- config['user'] = options['user'] if options['user']
163
- config['server'] = options['url']
164
- config['insecure'] = options['insecure'] || false
165
- config['server_type'] = options['server_type'].to_s
166
- config['token'] = token
167
- config['version'] = Compliance::API.version(config)
168
-
169
- config.store
170
- config
171
- end
172
-
173
- # Compliance login requires `--user` or `--refresh_token`
174
- # If `--user` then either `--password`, `--token`, or `--refresh-token`, is required
175
- def self.compliance_verify_thor_options(o)
176
- error_msg = []
177
-
178
- error_msg.push('Please specify a server using `inspec compliance login https://SERVER`') if o['server'].nil?
179
-
180
- if o['user'].nil? && o['refresh_token'].nil?
181
- error_msg.push('Please specify a `--user=\'USER\'` or a `--refresh-token=\'TOKEN\'`')
182
- end
183
-
184
- if o['user'] && o['password'].nil? && o['token'].nil? && o['refresh_token'].nil?
185
- error_msg.push('Please specify either a `--password`, `--token`, or `--refresh-token`')
186
- end
187
-
188
- raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
189
- end
190
- end
191
- end
192
- end
193
- end