inspec 0.9.11 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +45 -2
- data/bin/inspec +53 -86
- data/examples/kitchen-ansible/.kitchen/default-ubuntu-1404.yml +2 -2
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +25 -25
- data/examples/kitchen-ansible/.kitchen/logs/default-centos-71.log +0 -4
- data/examples/kitchen-ansible/.kitchen/logs/default-ubuntu-1204.log +0 -4
- data/examples/kitchen-ansible/.kitchen/logs/default-ubuntu-1404.log +395 -4
- data/examples/kitchen-ansible/.kitchen/logs/kitchen.log +3 -8
- data/examples/kitchen-ansible/Gemfile.lock +29 -25
- data/examples/kitchen-ansible/test/.DS_Store +0 -0
- data/examples/kitchen-ansible/test/integration/.DS_Store +0 -0
- data/examples/kitchen-azure/.kitchen.yml +30 -0
- data/examples/kitchen-azure/.kitchen/default-debian-80-20151022-x86-64.yml +1 -0
- data/examples/kitchen-azure/.kitchen/default-ubuntu-1204.yml +9 -0
- data/examples/kitchen-azure/.kitchen/logs/default-debian-80-20151022-x86-64.log +59 -0
- data/examples/kitchen-azure/.kitchen/logs/default-ubuntu-1204.log +27 -0
- data/{lib/resources/certificate.rb → examples/kitchen-azure/.kitchen/logs/default-windows2012-r2.log} +0 -0
- data/examples/kitchen-azure/.kitchen/logs/kitchen.log +29 -0
- data/examples/kitchen-azure/Berksfile +3 -0
- data/examples/kitchen-azure/Gemfile +20 -0
- data/examples/kitchen-azure/Gemfile.lock +273 -0
- data/examples/kitchen-azure/README.md +14 -0
- data/{lib/resources/private_key.rb → examples/kitchen-azure/credentials.sh} +0 -0
- data/examples/kitchen-azure/metadata.rb +7 -0
- data/examples/kitchen-azure/recipes/default.rb +6 -0
- data/examples/kitchen-azure/recipes/nginx.rb +30 -0
- data/examples/kitchen-azure/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-chef/.kitchen/default-ubuntu-1404.yml +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +25 -25
- data/examples/kitchen-chef/.kitchen/logs/default-centos-71.log +0 -4
- data/examples/kitchen-chef/.kitchen/logs/default-ubuntu-1204.log +0 -4
- data/examples/kitchen-chef/.kitchen/logs/default-ubuntu-1404.log +3 -4
- data/examples/kitchen-chef/.kitchen/logs/kitchen.log +3 -8
- data/examples/kitchen-chef/Gemfile.lock +27 -24
- data/examples/kitchen-chef/test/integration/.DS_Store +0 -0
- data/examples/{kitchen-chef/.kitchen/default-ubuntu-1204.yml → kitchen-puppet/.kitchen/default-ubuntu-1404.yml} +1 -1
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/.vagrant/machines/default/virtualbox/creator_uid +0 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +27 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/.vagrant/machines/default/virtualbox/synced_folders +0 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/Vagrantfile +3 -3
- data/examples/kitchen-puppet/.kitchen/logs/default-centos-71.log +0 -5
- data/examples/kitchen-puppet/.kitchen/logs/default-ubuntu-1204.log +0 -5
- data/examples/kitchen-puppet/.kitchen/logs/default-ubuntu-1404.log +305 -5
- data/examples/kitchen-puppet/.kitchen/logs/kitchen.log +6 -5
- data/examples/kitchen-puppet/.librarian/puppet/config +1 -1
- data/examples/kitchen-puppet/Gemfile.lock +22 -21
- data/examples/kitchen-puppet/test/integration/.DS_Store +0 -0
- data/examples/kitchen-puppet/test/integration/default/.DS_Store +0 -0
- data/examples/profile/controls/example.rb +7 -1
- data/lib/bundles/README.md +3 -0
- data/lib/bundles/inspec-compliance.rb +14 -0
- data/lib/bundles/inspec-compliance/README.md +20 -0
- data/lib/bundles/inspec-compliance/TODO.md +4 -0
- data/lib/bundles/inspec-compliance/api.rb +134 -0
- data/lib/bundles/inspec-compliance/cli.rb +146 -0
- data/lib/bundles/inspec-compliance/configuration.rb +52 -0
- data/lib/bundles/inspec-compliance/target.rb +61 -0
- data/lib/bundles/inspec-supermarket.rb +14 -0
- data/lib/bundles/inspec-supermarket/README.md +31 -0
- data/lib/bundles/inspec-supermarket/TODO.md +5 -0
- data/lib/bundles/inspec-supermarket/api.rb +58 -0
- data/lib/bundles/inspec-supermarket/cache.rb +30 -0
- data/lib/bundles/inspec-supermarket/cli.rb +54 -0
- data/lib/bundles/inspec-supermarket/target.rb +49 -0
- data/lib/inspec.rb +9 -2
- data/lib/inspec/metadata.rb +21 -7
- data/lib/inspec/plugins.rb +41 -0
- data/lib/inspec/plugins/cli.rb +24 -0
- data/lib/inspec/profile.rb +90 -61
- data/lib/inspec/rule.rb +9 -0
- data/lib/inspec/runner.rb +7 -3
- data/lib/inspec/runner_rspec.rb +19 -0
- data/lib/inspec/targets/archive.rb +14 -10
- data/lib/inspec/targets/tar.rb +3 -2
- data/lib/inspec/targets/url.rb +5 -4
- data/lib/inspec/targets/zip.rb +3 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/file.rb +7 -21
- data/lib/resources/os.rb +1 -1
- data/lib/resources/service.rb +15 -3
- data/lib/utils/base_cli.rb +131 -0
- data/lib/utils/find_files.rb +1 -1
- data/lib/utils/json_log.rb +17 -0
- data/test/helper.rb +39 -25
- data/test/integration/.kitchen.chef.yml +1 -1
- data/test/integration/.kitchen.ec2.yml +2 -0
- data/test/integration/.kitchen/default-aws-linux.yml +4 -0
- data/test/integration/.kitchen/default-centos-7.yml +4 -0
- data/test/integration/.kitchen/default-chef-solaris-113.yml +6 -0
- data/test/integration/.kitchen/default-chef-windows-server-2008r2-standard.yml +1 -1
- data/test/integration/.kitchen/default-debian-8.yml +4 -0
- data/test/integration/.kitchen/default-fedora-22.yml +4 -0
- data/test/integration/.kitchen/default-redhat-65.yml +4 -0
- data/test/integration/.kitchen/default-redhat-71.yml +4 -0
- data/test/integration/.kitchen/default-suse-11sp3.yml +4 -0
- data/test/integration/.kitchen/default-suse-12.yml +4 -0
- data/test/integration/.kitchen/default-suse-hi11sp3.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1204.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1404.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1510.yml +4 -0
- data/test/integration/.kitchen/default-windows-2012r2.yml +6 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/{examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204 → test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113}/.vagrant/machines/default/virtualbox/creator_uid +0 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/id +1 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/index_uuid +1 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/private_key +27 -0
- data/{examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204 → test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113}/.vagrant/machines/default/virtualbox/synced_folders +0 -0
- data/test/integration/.kitchen/kitchen-vagrant/{kitchen-integration-default-chef-windows-server-2012r2-standard → kitchen-integration-default-chef-solaris-113}/Vagrantfile +2 -2
- data/test/integration/.kitchen/logs/default-aws-linux.log +0 -3
- data/test/integration/.kitchen/logs/default-centos-7.log +0 -3
- data/test/integration/.kitchen/logs/default-chef-solaris-113.log +0 -0
- data/test/integration/.kitchen/logs/default-chef-windows-server-2008r2-standard.log +43 -0
- data/test/integration/.kitchen/logs/default-chris-rock-omnios-r151014.log +41 -23
- data/test/integration/.kitchen/logs/default-debian-8.log +0 -3
- data/test/integration/.kitchen/logs/default-fedora-22.log +0 -3
- data/test/integration/.kitchen/logs/default-redhat-65.log +0 -3
- data/test/integration/.kitchen/logs/default-redhat-71.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-11sp3.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-12.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-hi11sp3.log +37 -0
- data/test/integration/.kitchen/logs/default-ubuntu-1204.log +23 -3
- data/test/integration/.kitchen/logs/default-ubuntu-1404.log +0 -3
- data/test/integration/.kitchen/logs/default-ubuntu-1510.log +0 -3
- data/test/integration/.kitchen/logs/default-windows-2012r2.log +0 -2
- data/test/integration/.kitchen/logs/kitchen.log +3 -14
- data/test/integration/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +21 -0
- data/test/integration/cookbooks/os_prepare/recipes/apache.rb +14 -0
- data/test/integration/cookbooks/os_prepare/recipes/service.rb +1 -0
- data/test/integration/test/integration/default/service_spec.rb +24 -0
- data/test/solaris_test.rb +70 -0
- data/test/unit/mock/cmd/initctl--version +5 -0
- data/test/unit/plugin_test.rb +46 -0
- data/test/unit/profile_test.rb +136 -21
- data/test/unit/resources/file_test.rb +13 -25
- metadata +105 -51
- data/examples/kitchen-ansible/.kitchen/default-centos-71.yml +0 -6
- data/examples/kitchen-ansible/.kitchen/default-ubuntu-1204.yml +0 -6
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/Vagrantfile +0 -9
- data/examples/kitchen-chef/.kitchen/default-centos-71.yml +0 -6
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/synced_folders +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/Vagrantfile +0 -9
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/synced_folders +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/Vagrantfile +0 -9
- data/test/integration/.kitchen/default-chef-windows-server-2012r2-standard.yml +0 -7
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/id +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/synced_folders +0 -1
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
module Compliance
|
6
|
+
# stores configuration on local filesystem
|
7
|
+
class Configuration
|
8
|
+
def initialize
|
9
|
+
@config_path = File.join(Dir.home, '.inspec', 'compliance')
|
10
|
+
# ensure the directory is available
|
11
|
+
unless File.directory?(@config_path)
|
12
|
+
FileUtils.mkdir_p(@config_path)
|
13
|
+
end
|
14
|
+
# set config file path
|
15
|
+
@config_file = File.join(@config_path, '/config.json')
|
16
|
+
@config = {}
|
17
|
+
|
18
|
+
# load the data
|
19
|
+
get
|
20
|
+
end
|
21
|
+
|
22
|
+
# direct access to config
|
23
|
+
def [](key)
|
24
|
+
@config[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
def []=(key, value)
|
28
|
+
@config[key] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
# return the json data
|
32
|
+
def get
|
33
|
+
if File.exist?(@config_file)
|
34
|
+
file = File.read(@config_file)
|
35
|
+
@config = JSON.parse(file)
|
36
|
+
end
|
37
|
+
@config
|
38
|
+
end
|
39
|
+
|
40
|
+
# stores a hash to json
|
41
|
+
def store
|
42
|
+
File.open(@config_file, 'w') do |f|
|
43
|
+
f.write(@config.to_json)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# deletes data
|
48
|
+
def destroy
|
49
|
+
File.delete(@config_file)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
# InSpec Target Helper for Chef Compliance
|
8
|
+
# reuses UrlHelper, but it knows the target server and the access token already
|
9
|
+
# similar to `inspec exec http://localhost:2134/owners/%base%/compliance/%ssh%/tar --user %token%`
|
10
|
+
module Compliance
|
11
|
+
class ChefComplianceHelper < Inspec::Targets::UrlHelper
|
12
|
+
def handles?(target)
|
13
|
+
# check for local scheme compliance://
|
14
|
+
uri = URI(target)
|
15
|
+
return unless URI(uri).scheme == 'compliance'
|
16
|
+
|
17
|
+
# check if we have a compliance token
|
18
|
+
config = Compliance::Configuration.new
|
19
|
+
return if config['token'].nil?
|
20
|
+
|
21
|
+
# get profile name
|
22
|
+
profile = get_profile_name(uri)
|
23
|
+
|
24
|
+
# verifies that the target e.g base/ssh exists
|
25
|
+
Compliance::API.exist?(profile)
|
26
|
+
rescue URI::Error => _e
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
# generates proper url
|
31
|
+
def resolve(target, opts = {})
|
32
|
+
profile = get_profile_name(URI(target))
|
33
|
+
# generates server url
|
34
|
+
target = build_target_url(profile)
|
35
|
+
config = Compliance::Configuration.new
|
36
|
+
opts['user'] = config['token']
|
37
|
+
puts target
|
38
|
+
super(target, opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
# extracts profile name from url
|
42
|
+
def get_profile_name(uri)
|
43
|
+
uri.host + uri.path
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_target_url(target)
|
47
|
+
owner, profile = target.split('/')
|
48
|
+
config = Compliance::Configuration.new
|
49
|
+
url = "#{config['server']}/owners/%owner_name%/compliance/%profile_name%/tar"
|
50
|
+
.gsub('%owner_name%', owner)
|
51
|
+
.gsub('%profile_name%', profile)
|
52
|
+
url
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
'Chef Compliance Profile Loader'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Inspec::Targets.add_module('chefcompliance', ChefComplianceHelper.new)
|
61
|
+
end
|
@@ -0,0 +1,14 @@
|
|
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 Supermarket
|
9
|
+
autoload :Configuration, 'inspec-supermarket/configuration'
|
10
|
+
autoload :API, 'inspec-supermarket/api'
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'inspec-supermarket/cli'
|
14
|
+
require 'inspec-supermarket/target'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# InSpec Extension for Chef Supermarket
|
2
|
+
|
3
|
+
To use the CLI, this InSpec add-on adds the following commands:
|
4
|
+
|
5
|
+
* `$ inspec supermarket configure` - configures the supermarket server
|
6
|
+
* `$ inspec supermarket search` - searches for a compliance profile on supermarket
|
7
|
+
* `$ inspec supermarket exec nathenharvey/tmp-compliance-profile` - extends execute to load the profile
|
8
|
+
|
9
|
+
Compliance profiles from Supermarket can be executed in two mays:
|
10
|
+
|
11
|
+
- via supermarket exec: `inspec supermarket exec nathenharvey/tmp-compliance-profile`
|
12
|
+
- via supermarket scheme: `inspec exec supermarket://nathenharvey/tmp-compliance-profile`
|
13
|
+
|
14
|
+
|
15
|
+
# fetch all available profiles in local cache
|
16
|
+
# https://supermarket.chef.io/api/v1/tools-search\?q\=compliance_profile
|
17
|
+
|
18
|
+
# get the tool slug url
|
19
|
+
# https://supermarket.chef.io/api/v1/tools/tmp-compliance-profile
|
20
|
+
# https://supermarket.chef.io/api/v1/tools/tmp_compliance_profile
|
21
|
+
# response
|
22
|
+
# {
|
23
|
+
# "description": "An InSpec compliance profile for use with Chef Compliance Server.\r\n",
|
24
|
+
# "instructions": "## Installation\r\n\r\nDownload the [latest release](https://github.com/nathenharvey/tmp_compliance_profile/releases) from GitHub and upload the tar.gz to your Chef Compliance Server.\r\n\r\n## Controls Included\r\n\r\n* tmp-1.0 - A /tmp directory must exist\r\n* tmp-1.1 - The /tmp directory must be owned by the root user\r\n\r\n## License & Authors\r\n\r\n*Author:* Nathen Harvey\r\n\r\n*Copyright:* 2015-2016, Chef Software, Inc.\r\n\r\n Licensed under the Apache License, Version 2.0 (the \"License\");\r\n you may not use this file except in compliance with the License.\r\n You may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n Unless required by applicable law or agreed to in writing, software\r\n distributed under the License is distributed on an \"AS IS\" BASIS,\r\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n See the License for the specific language governing permissions and\r\n limitations under the License.\r\n",
|
25
|
+
# "name": "/tmp Compliance Profile",
|
26
|
+
# "owner": "nathenharvey",
|
27
|
+
# "slug": "tmp-compliance-profile",
|
28
|
+
# "source_url": "https://github.com/nathenharvey/tmp_compliance_profile/",
|
29
|
+
# "type": "compliance_profile",
|
30
|
+
# "up_for_adoption": false
|
31
|
+
# }
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
module Supermarket
|
6
|
+
class API
|
7
|
+
def self.profiles
|
8
|
+
url = 'https://supermarket.chef.io/api/v1/tools-search'
|
9
|
+
data = get(url, { :q => 'compliance_profile' })
|
10
|
+
if !data.nil?
|
11
|
+
profiles = JSON.parse(data)
|
12
|
+
profiles['items']
|
13
|
+
# val = []
|
14
|
+
# # iterate over profiles
|
15
|
+
# profiles.each_key { |org|
|
16
|
+
# profiles[org].each_key { |name|
|
17
|
+
# val.push({ org: org, name: name})
|
18
|
+
# }
|
19
|
+
# }
|
20
|
+
# val
|
21
|
+
else
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.info(slug)
|
27
|
+
url = "https://supermarket.chef.io/api/v1/tools/#{slug}"
|
28
|
+
data = get(url, {})
|
29
|
+
if !data.nil?
|
30
|
+
info = JSON.parse(data)
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def self.get(url, params)
|
39
|
+
uri = URI.parse(url)
|
40
|
+
uri.query = URI.encode_www_form(params)
|
41
|
+
req = Net::HTTP::Get.new(uri)
|
42
|
+
send_request(uri, req)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.send_request(uri, req)
|
46
|
+
# send request
|
47
|
+
res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') {|http|
|
48
|
+
http.request(req)
|
49
|
+
}
|
50
|
+
if res.is_a?(Net::HTTPSuccess)
|
51
|
+
res.body
|
52
|
+
else
|
53
|
+
puts res.body
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
module Supermarket
|
6
|
+
class Cache
|
7
|
+
def initialize
|
8
|
+
@config_path = File.join(ENV['HOME'], '/.inspec')
|
9
|
+
# ensure the directory is available
|
10
|
+
unless File.directory?(@config_path)
|
11
|
+
FileUtils.mkdir_p(@config_path)
|
12
|
+
end
|
13
|
+
# set cache file path
|
14
|
+
@cache_file = File.join(@config_path, '/supermarket-cache.json')
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_cache(data)
|
18
|
+
File.open(@cache_file,"w") do |f|
|
19
|
+
f.write(data.to_json)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def retrieve_cache
|
24
|
+
if File.exists?(@cache_file)
|
25
|
+
file = File.read(@cache_file)
|
26
|
+
JSON.parse(file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
module Supermarket
|
6
|
+
class SupermarketCLI < Inspec::BaseCLI
|
7
|
+
namespace 'supermarket'
|
8
|
+
|
9
|
+
desc 'configure SERVER', 'Changes the default supermarket https://supermarket.chef.io/api/v1/'
|
10
|
+
def configure(server)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'profiles', 'list all available profiles in Chef Supermarket'
|
14
|
+
def profiles
|
15
|
+
# display profiles in format nathenharvey/tmp_compliance_profile
|
16
|
+
supermarket_profiles = Supermarket::API.profiles
|
17
|
+
supermarket_profiles.each { |p|
|
18
|
+
m = %r{^https://supermarket.chef.io/api/v1/tools/(?<slug>[\w-]+)(/)?$}.match(p['tool'])
|
19
|
+
puts "#{p['tool_owner']}/#{m[:slug]}"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'exec PROFILE', 'executes a Supermarket profile'
|
24
|
+
option :id, type: :string,
|
25
|
+
desc: 'Attach a profile ID to all test results'
|
26
|
+
target_options
|
27
|
+
option :format, type: :string
|
28
|
+
def exec(*tests)
|
29
|
+
# iterate over tests and add compliance scheme
|
30
|
+
tests = tests.map { |t| 'supermarket://' + t }
|
31
|
+
|
32
|
+
# execute profile from inspec exec implementation
|
33
|
+
diagnose
|
34
|
+
run_tests(opts, tests)
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'info profile', 'display profile details'
|
38
|
+
def info(profile)
|
39
|
+
# display profiles in format nathenharvey/tmp-compliance-profile
|
40
|
+
# name: tmp_compliance_profile
|
41
|
+
# owner: nathenharvey
|
42
|
+
# description: ...
|
43
|
+
info = Supermarket::API.info('tmp-compliance-profile')
|
44
|
+
puts "name: #{info['slug']}"
|
45
|
+
puts "owner: #{info['owner']} "
|
46
|
+
puts "url: #{info['source_url']}"
|
47
|
+
puts "\n"
|
48
|
+
puts "description:\n#{info['description']}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# register the subcommand to Inspec CLI registry
|
53
|
+
Inspec::Plugins::CLI.register(Supermarket::SupermarketCLI, "supermarket", "supermarket SUBCOMMAND ...", "Supermarket commands", {})
|
54
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
# InSpec Target Helper for Supermarket
|
8
|
+
module Supermarket
|
9
|
+
class SupermarketHelper < Inspec::Targets::UrlHelper
|
10
|
+
def handles?(profile)
|
11
|
+
# check for local scheme supermarket://
|
12
|
+
return unless URI(profile).scheme == 'supermarket'
|
13
|
+
# emulate supermarket namespace
|
14
|
+
profile == 'supermarket://nathenharvey/tmp-compliance-profile'
|
15
|
+
rescue URI::Error => e
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
# generates proper url
|
20
|
+
def resolve(profile, opts = {})
|
21
|
+
profile = get_profile_name(URI(target))
|
22
|
+
target = build_target_url(profile)
|
23
|
+
super(target, opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
# extracts profile name from url
|
27
|
+
def get_profile_name(uri)
|
28
|
+
uri.host + uri.path
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_target_url(target)
|
32
|
+
|
33
|
+
# read details from json
|
34
|
+
# extracts github url
|
35
|
+
|
36
|
+
supermarket, slug = target.split('/')
|
37
|
+
# search profile with slug
|
38
|
+
# get github url
|
39
|
+
# return github url
|
40
|
+
"https://github.com/nathenharvey/tmp_compliance_profile/"
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
'Chef Compliance Profile Loader'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Inspec::Targets.add_module('supermarket', Supermarket::SupermarketHelper.new)
|
49
|
+
end
|
data/lib/inspec.rb
CHANGED
@@ -12,9 +12,16 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
|
12
12
|
|
13
13
|
require 'inspec/version'
|
14
14
|
require 'inspec/profile'
|
15
|
-
require 'inspec/resource'
|
16
15
|
require 'inspec/rspec_json_formatter'
|
17
16
|
require 'inspec/rule'
|
17
|
+
require 'matchers/matchers'
|
18
18
|
require 'inspec/runner'
|
19
19
|
require 'inspec/shell'
|
20
|
-
|
20
|
+
|
21
|
+
# all utils that may be required by plugins
|
22
|
+
require 'utils/base_cli'
|
23
|
+
|
24
|
+
# ensure resource and plugins are loaded after runner, because the runner loads
|
25
|
+
# targets
|
26
|
+
require 'inspec/resource'
|
27
|
+
require 'inspec/plugins'
|
data/lib/inspec/metadata.rb
CHANGED
@@ -100,19 +100,27 @@ module Inspec
|
|
100
100
|
!found.nil?
|
101
101
|
end
|
102
102
|
|
103
|
-
|
104
|
-
|
103
|
+
# return all warn and errors
|
104
|
+
def valid
|
105
|
+
errors = []
|
106
|
+
warnings = []
|
107
|
+
|
105
108
|
%w{ name version }.each do |field|
|
106
109
|
next unless params[field.to_sym].nil?
|
107
|
-
|
108
|
-
is_valid = false
|
110
|
+
errors.push("Missing profile #{field} in #{ref}")
|
109
111
|
end
|
110
112
|
%w{ title summary maintainer copyright }.each do |field|
|
111
113
|
next unless params[field.to_sym].nil?
|
112
|
-
|
113
|
-
is_valid = false
|
114
|
+
warnings.push("Missing profile #{field} in #{ref}")
|
114
115
|
end
|
115
|
-
|
116
|
+
|
117
|
+
[errors, warnings]
|
118
|
+
end
|
119
|
+
|
120
|
+
# returns true or false
|
121
|
+
def valid?
|
122
|
+
errors, _warnings = valid
|
123
|
+
errors.empty? && unsupported.empty?
|
116
124
|
end
|
117
125
|
|
118
126
|
def method_missing(sth, *args)
|
@@ -120,6 +128,10 @@ module Inspec
|
|
120
128
|
@missing_methods.push(sth)
|
121
129
|
end
|
122
130
|
|
131
|
+
def unsupported
|
132
|
+
@missing_methods
|
133
|
+
end
|
134
|
+
|
123
135
|
def self.symbolize_keys(hash)
|
124
136
|
hash.each_with_object({}) {|(k, v), h|
|
125
137
|
v = symbolize_keys(v) if v.is_a?(Hash)
|
@@ -146,6 +158,8 @@ module Inspec
|
|
146
158
|
end
|
147
159
|
|
148
160
|
def self.from_ref(ref, contents, profile_id, logger = nil)
|
161
|
+
# NOTE there doesn't have to exist an actual file, it may come from an
|
162
|
+
# archive (i.e., contents)
|
149
163
|
case File.basename(ref)
|
150
164
|
when 'inspec.yml'
|
151
165
|
from_yaml(ref, contents, profile_id, logger)
|
data/lib/inspec/plugins.rb
CHANGED
@@ -2,8 +2,49 @@
|
|
2
2
|
# author: Dominik Richter
|
3
3
|
# author: Christoph Hartmann
|
4
4
|
|
5
|
+
require 'forwardable'
|
6
|
+
|
5
7
|
module Inspec
|
8
|
+
# Resource Plugins
|
6
9
|
module Plugins
|
7
10
|
autoload :Resource, 'inspec/plugins/resource'
|
11
|
+
autoload :CLI, 'inspec/plugins/cli'
|
12
|
+
end
|
13
|
+
|
14
|
+
class PluginCtl
|
15
|
+
extend Forwardable
|
16
|
+
|
17
|
+
attr_reader :registry
|
18
|
+
def_delegator :registry, :keys, :list
|
19
|
+
|
20
|
+
def initialize(home = nil)
|
21
|
+
@home = home || File.join(Dir.home, '.inspec', 'plugins')
|
22
|
+
@paths = Dir[File.join(@home, '**{,/*/**}', '*.gemspec')]
|
23
|
+
.map { |x| File.dirname(x) }
|
24
|
+
.map { |x| Dir[File.join(x, 'lib', 'inspec-*.rb')] }
|
25
|
+
.flatten
|
26
|
+
|
27
|
+
# load bundled plugins
|
28
|
+
bundled_dir = File.expand_path(File.dirname(__FILE__))
|
29
|
+
@paths += Dir[File.join(bundled_dir, '..', 'bundles', 'inspec-*.rb')].flatten
|
30
|
+
|
31
|
+
# map paths to names
|
32
|
+
@registry = Hash[@paths.map { |x|
|
33
|
+
[File.basename(x, '.rb'), x]
|
34
|
+
}]
|
35
|
+
end
|
36
|
+
|
37
|
+
def load(name)
|
38
|
+
path = @registry[name]
|
39
|
+
if path.nil?
|
40
|
+
fail "Couldn't find plugin #{name}. Searching in #{@home}"
|
41
|
+
end
|
42
|
+
# puts "Loading plugin #{name} from #{path}"
|
43
|
+
require path
|
44
|
+
end
|
8
45
|
end
|
9
46
|
end
|
47
|
+
|
48
|
+
# Load all plugins on startup
|
49
|
+
ctl = Inspec::PluginCtl.new
|
50
|
+
ctl.list.each { |x| ctl.load(x) }
|