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
@@ -1,41 +0,0 @@
1
- #!/bin/bash
2
-
3
- echo "Installing Chef Compliance $deb"
4
- # select latest package from cache directory
5
- # deb=$(find /inspec/.cache -name '*.deb' | tail -1)
6
- # sudo dpkg -i $deb
7
-
8
- # use chef compliance package repository
9
- sudo apt-get install -y apt-transport-https
10
- sudo apt-get install wget
11
- wget -qO - https://downloads.chef.io/packages-chef-io-public.key | sudo apt-key add -
12
- CHANNEL=${CHANNEL:-stable}
13
- DISTRIBUTION=$(lsb_release --codename | cut -f2)
14
- echo "found $DISTRIBUTION"
15
- echo "use $CHANNEL channel"
16
- echo "deb https://packages.chef.io/$CHANNEL-apt $DISTRIBUTION main" > /etc/apt/sources.list.d/chef-$CHANNEL.list
17
- sudo apt-get update
18
- sudo apt-get install chef-compliance
19
-
20
- sudo chef-compliance-ctl reconfigure --accept-license
21
- sudo chef-compliance-ctl restart
22
-
23
- # finalize setup
24
- cd /
25
- /opt/chef-compliance/embedded/service/core/bin/core setup --endpoint "http://127.0.0.1:10500/setup" --login "admin" --password "admin" --name "John Doe" --accept-eula
26
-
27
- # wget --no-check-certificate http://127.0.0.1/api/version
28
- # cat version
29
-
30
- # install ruby 2.3
31
- sudo apt-get install -y software-properties-common
32
- sudo apt-add-repository -y ppa:brightbox/ruby-ng
33
- sudo apt-get update
34
- sudo apt-get install -y ruby2.3 ruby2.3-dev
35
- ruby2.3 -v
36
-
37
- # prepare the usage of bundler
38
- sudo gem install bundler
39
- cd /inspec
40
- bundle install
41
- BUNDLE_GEMFILE=/inspec/Gemfile bundle exec inspec version
@@ -1,276 +0,0 @@
1
- # encoding: utf-8
2
- # author: Christoph Hartmann
3
- # author: Dominik Richter
4
-
5
- require 'thor'
6
- require 'erb'
7
- require 'inspec/base_cli'
8
-
9
- module Compliance
10
- class ComplianceCLI < Inspec::BaseCLI
11
- namespace 'compliance'
12
-
13
- # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
14
- def self.banner(command, _namespace = nil, _subcommand = false)
15
- "#{basename} #{subcommand_prefix} #{command.usage}"
16
- end
17
-
18
- def self.subcommand_prefix
19
- namespace
20
- end
21
-
22
- desc "login https://SERVER --insecure --user='USER' --ent='ENTERPRISE' --token='TOKEN'", 'Log in to a Chef Compliance/Chef Automate SERVER'
23
- long_desc <<-LONGDESC
24
- `login` allows you to use InSpec with Chef Automate or a Chef Compliance Server
25
-
26
- You need to a token for communication. More information about token retrieval
27
- is available at:
28
- https://docs.chef.io/api_automate.html#authentication-methods
29
- https://docs.chef.io/api_compliance.html#obtaining-an-api-token
30
- LONGDESC
31
- option :insecure, aliases: :k, type: :boolean,
32
- desc: 'Explicitly allows InSpec to perform "insecure" SSL connections and transfers'
33
- option :user, type: :string, required: false,
34
- desc: 'Username'
35
- option :password, type: :string, required: false,
36
- desc: 'Password (Chef Compliance Only)'
37
- option :token, type: :string, required: false,
38
- desc: 'Access token'
39
- option :refresh_token, type: :string, required: false,
40
- desc: 'Chef Compliance refresh token (Chef Compliance Only)'
41
- option :dctoken, type: :string, required: false,
42
- desc: 'Data Collector token (Chef Automate Only)'
43
- option :ent, type: :string, required: false,
44
- desc: 'Enterprise for Chef Automate reporting (Chef Automate Only)'
45
- def login(server)
46
- options['server'] = server
47
- Compliance::API.login(options)
48
- config = Compliance::Configuration.new
49
- puts "Stored configuration for Chef #{config['server_type'].capitalize}: #{config['server']}' with user: '#{config['user']}'"
50
- end
51
-
52
- desc 'profiles', 'list all available profiles in Chef Compliance'
53
- option :owner, type: :string, required: false,
54
- desc: 'owner whose profiles to list'
55
- def profiles
56
- config = Compliance::Configuration.new
57
- return if !loggedin(config)
58
-
59
- # set owner to config
60
- config['owner'] = options['owner'] || config['user']
61
-
62
- msg, profiles = Compliance::API.profiles(config)
63
- profiles.sort_by! { |hsh| hsh['title'] }
64
- if !profiles.empty?
65
- # iterate over profiles
66
- headline('Available profiles:')
67
- profiles.each { |profile|
68
- owner = profile['owner_id'] || profile['owner']
69
- li("#{profile['title']} v#{profile['version']} (#{mark_text(owner + '/' + profile['name'])})")
70
- }
71
- else
72
- puts msg if msg != 'success'
73
- puts 'Could not find any profiles'
74
- exit 1
75
- end
76
- rescue Compliance::ServerConfigurationMissing
77
- STDERR.puts "\nServer configuration information is missing. Please login using `inspec compliance login`"
78
- exit 1
79
- end
80
-
81
- desc 'exec PROFILE', 'executes a Chef Compliance profile'
82
- exec_options
83
- def exec(*tests)
84
- config = Compliance::Configuration.new
85
- return if !loggedin(config)
86
- o = opts(:exec).dup
87
- diagnose(o)
88
- configure_logger(o)
89
-
90
- # iterate over tests and add compliance scheme
91
- tests = tests.map { |t| 'compliance://' + Compliance::API.sanitize_profile_name(t) }
92
-
93
- runner = Inspec::Runner.new(o)
94
- tests.each { |target| runner.add_target(target) }
95
-
96
- exit runner.run
97
- rescue ArgumentError, RuntimeError, Train::UserError => e
98
- $stderr.puts e.message
99
- exit 1
100
- end
101
-
102
- desc 'download PROFILE', 'downloads a profile from Chef Compliance'
103
- option :name, type: :string,
104
- desc: 'Name of the archive filename (file type will be added)'
105
- def download(profile_name)
106
- o = options.dup
107
- configure_logger(o)
108
-
109
- config = Compliance::Configuration.new
110
- return if !loggedin(config)
111
-
112
- profile_name = Compliance::API.sanitize_profile_name(profile_name)
113
- if Compliance::API.exist?(config, profile_name)
114
- puts "Downloading `#{profile_name}`"
115
-
116
- fetcher = Compliance::Fetcher.resolve(
117
- {
118
- compliance: profile_name,
119
- },
120
- )
121
-
122
- # we provide a name, the fetcher adds the extension
123
- _owner, id = profile_name.split('/')
124
- file_name = fetcher.fetch(o.name || id)
125
- puts "Profile stored to #{file_name}"
126
- else
127
- puts "Profile #{profile_name} is not available in Chef Compliance."
128
- exit 1
129
- end
130
- end
131
-
132
- desc 'upload PATH', 'uploads a local profile to Chef Compliance'
133
- option :overwrite, type: :boolean, default: false,
134
- desc: 'Overwrite existing profile on Server.'
135
- option :owner, type: :string, required: false,
136
- desc: 'Owner that should own the profile'
137
- def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, PerceivedComplexity, Metrics/CyclomaticComplexity
138
- config = Compliance::Configuration.new
139
- return if !loggedin(config)
140
-
141
- # set owner to config
142
- config['owner'] = options['owner'] || config['user']
143
-
144
- unless File.exist?(path)
145
- puts "Directory #{path} does not exist."
146
- exit 1
147
- end
148
-
149
- vendor_deps(path, options) if File.directory?(path)
150
-
151
- o = options.dup
152
- configure_logger(o)
153
-
154
- # only run against the mock backend, otherwise we run against the local system
155
- o[:backend] = Inspec::Backend.create(target: 'mock://')
156
- o[:check_mode] = true
157
- o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
158
-
159
- # check the profile, we only allow to upload valid profiles
160
- profile = Inspec::Profile.for_target(path, o)
161
-
162
- # start verification process
163
- error_count = 0
164
- error = lambda { |msg|
165
- error_count += 1
166
- puts msg
167
- }
168
-
169
- result = profile.check
170
- unless result[:summary][:valid]
171
- error.call('Profile check failed. Please fix the profile before upload.')
172
- else
173
- puts('Profile is valid')
174
- end
175
-
176
- # determine user information
177
- if (config['token'].nil? && config['refresh_token'].nil?) || config['user'].nil?
178
- error.call('Please login via `inspec compliance login`')
179
- end
180
-
181
- # read profile name from inspec.yml
182
- profile_name = profile.params[:name]
183
-
184
- # read profile version from inspec.yml
185
- profile_version = profile.params[:version]
186
-
187
- # check that the profile is not uploaded already,
188
- # confirm upload to the user (overwrite with --force)
189
- if Compliance::API.exist?(config, "#{config['owner']}/#{profile_name}##{profile_version}") && !options['overwrite']
190
- error.call('Profile exists on the server, use --overwrite')
191
- end
192
-
193
- # abort if we found an error
194
- if error_count > 0
195
- puts "Found #{error_count} error(s)"
196
- exit 1
197
- end
198
-
199
- # if it is a directory, tar it to tmp directory
200
- generated = false
201
- if File.directory?(path)
202
- generated = true
203
- archive_path = Dir::Tmpname.create([profile_name, '.tar.gz']) {}
204
- puts "Generate temporary profile archive at #{archive_path}"
205
- profile.archive({ output: archive_path, ignore_errors: false, overwrite: true })
206
- else
207
- archive_path = path
208
- end
209
-
210
- puts "Start upload to #{config['owner']}/#{profile_name}"
211
- pname = ERB::Util.url_encode(profile_name)
212
-
213
- if Compliance::API.is_automate_server?(config) || Compliance::API.is_automate2_server?(config)
214
- puts 'Uploading to Chef Automate'
215
- else
216
- puts 'Uploading to Chef Compliance'
217
- end
218
- success, msg = Compliance::API.upload(config, config['owner'], pname, archive_path)
219
-
220
- # delete temp file if it was temporary generated
221
- File.delete(archive_path) if generated && File.exist?(archive_path)
222
-
223
- if success
224
- puts 'Successfully uploaded profile'
225
- else
226
- puts 'Error during profile upload:'
227
- puts msg
228
- exit 1
229
- end
230
- end
231
-
232
- desc 'version', 'displays the version of the Chef Compliance server'
233
- def version
234
- config = Compliance::Configuration.new
235
- info = Compliance::API.version(config)
236
- if !info.nil? && info['version']
237
- puts "Name: #{info['api']}"
238
- puts "Version: #{info['version']}"
239
- else
240
- puts 'Could not determine server version.'
241
- exit 1
242
- end
243
- rescue Compliance::ServerConfigurationMissing
244
- puts "\nServer configuration information is missing. Please login using `inspec compliance login`"
245
- exit 1
246
- end
247
-
248
- desc 'logout', 'user logout from Chef Compliance'
249
- def logout
250
- config = Compliance::Configuration.new
251
- unless config.supported?(:oidc) || config['token'].nil? || config['server_type'] == 'automate'
252
- config = Compliance::Configuration.new
253
- url = "#{config['server']}/logout"
254
- Compliance::HTTP.post(url, config['token'], config['insecure'], !config.supported?(:oidc))
255
- end
256
- success = config.destroy
257
-
258
- if success
259
- puts 'Successfully logged out'
260
- else
261
- puts 'Could not log out'
262
- end
263
- end
264
-
265
- private
266
-
267
- def loggedin(config)
268
- serverknown = !config['server'].nil?
269
- puts 'You need to login first with `inspec compliance login`' if !serverknown
270
- serverknown
271
- end
272
- end
273
-
274
- # register the subcommand to Inspec CLI registry
275
- Inspec::Plugins::CLI.add_subcommand(ComplianceCLI, 'compliance', 'compliance SUBCOMMAND ...', 'Chef Compliance commands', {})
276
- end