inspec-core 2.3.5 → 2.3.10

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -8
  3. data/lib/bundles/inspec-compliance/api.rb +3 -353
  4. data/lib/bundles/inspec-compliance/configuration.rb +3 -102
  5. data/lib/bundles/inspec-compliance/http.rb +3 -115
  6. data/lib/bundles/inspec-compliance/support.rb +3 -35
  7. data/lib/bundles/inspec-compliance/target.rb +3 -142
  8. data/lib/inspec/base_cli.rb +4 -1
  9. data/lib/inspec/cli.rb +1 -1
  10. data/lib/inspec/control_eval_context.rb +2 -2
  11. data/lib/inspec/version.rb +1 -1
  12. data/lib/matchers/matchers.rb +3 -3
  13. data/lib/{bundles → plugins}/inspec-compliance/README.md +0 -0
  14. data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +12 -0
  15. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +358 -0
  16. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +192 -0
  17. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +266 -0
  18. data/lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb +103 -0
  19. data/lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb +116 -0
  20. data/lib/{bundles → plugins/inspec-compliance/lib}/inspec-compliance/images/cc-token.png +0 -0
  21. data/lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb +36 -0
  22. data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +143 -0
  23. data/lib/plugins/inspec-compliance/test/functional/inspec_compliance_test.rb +43 -0
  24. data/lib/{bundles → plugins}/inspec-compliance/test/integration/default/cli.rb +0 -0
  25. data/lib/plugins/inspec-compliance/test/unit/api/login_test.rb +190 -0
  26. data/lib/plugins/inspec-compliance/test/unit/api_test.rb +385 -0
  27. data/lib/plugins/inspec-compliance/test/unit/target_test.rb +155 -0
  28. data/lib/resources/processes.rb +19 -3
  29. metadata +17 -10
  30. data/lib/bundles/inspec-compliance.rb +0 -16
  31. data/lib/bundles/inspec-compliance/.kitchen.yml +0 -20
  32. data/lib/bundles/inspec-compliance/api/login.rb +0 -193
  33. data/lib/bundles/inspec-compliance/bootstrap.sh +0 -41
  34. 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