inspec 1.0.0 → 1.35.1
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/CHANGELOG.md +933 -101
- data/Gemfile +8 -17
- data/MAINTAINERS.md +2 -1
- data/MAINTAINERS.toml +9 -4
- data/README.md +49 -28
- data/Rakefile +54 -39
- data/bin/inspec +1 -1
- data/docs/dsl_inspec.md +17 -4
- data/docs/dsl_resource.md +1 -1
- data/docs/habitat.md +192 -0
- data/docs/inspec_and_friends.md +4 -2
- data/docs/matchers.md +11 -0
- data/docs/migration.md +293 -0
- data/docs/profiles.md +124 -76
- data/docs/resources/aide_conf.md.erb +81 -0
- data/docs/resources/apache_conf.md.erb +10 -10
- data/docs/resources/apt.md.erb +13 -13
- data/docs/resources/audit_policy.md.erb +10 -10
- data/docs/resources/auditd_conf.md.erb +10 -10
- data/docs/resources/auditd_rules.md.erb +11 -11
- data/docs/resources/bash.md.erb +12 -12
- data/docs/resources/bond.md.erb +15 -15
- data/docs/resources/bridge.md.erb +11 -11
- data/docs/resources/bsd_service.md.erb +11 -11
- data/docs/resources/command.md.erb +23 -23
- data/docs/resources/crontab.md.erb +84 -0
- data/docs/resources/csv.md.erb +10 -10
- data/docs/resources/dh_params.md +191 -0
- data/docs/resources/directory.md.erb +8 -8
- data/docs/resources/docker.md.erb +160 -0
- data/docs/resources/docker_container.md.erb +89 -0
- data/docs/resources/docker_image.md.erb +86 -0
- data/docs/resources/etc_group.md.erb +16 -16
- data/docs/resources/etc_hosts.md.erb +62 -0
- data/docs/resources/file.md.erb +80 -58
- data/docs/resources/gem.md.erb +32 -13
- data/docs/resources/group.md.erb +12 -12
- data/docs/resources/grub_conf.md.erb +11 -11
- data/docs/resources/host.md.erb +27 -18
- data/docs/resources/http.md.erb +104 -0
- data/docs/resources/iis_app.md.erb +126 -0
- data/docs/resources/iis_site.md.erb +17 -17
- data/docs/resources/inetd_conf.md.erb +10 -10
- data/docs/resources/ini.md.erb +9 -9
- data/docs/resources/interface.md.erb +13 -13
- data/docs/resources/iptables.md.erb +21 -14
- data/docs/resources/json.md.erb +11 -11
- data/docs/resources/kernel_module.md.erb +73 -12
- data/docs/resources/kernel_parameter.md.erb +12 -12
- data/docs/resources/key_rsa.md.erb +70 -0
- data/docs/resources/launchd_service.md.erb +11 -11
- data/docs/resources/limits_conf.md.erb +10 -10
- data/docs/resources/login_def.md.erb +12 -12
- data/docs/resources/mount.md.erb +14 -14
- data/docs/resources/mssql_session.md.erb +62 -0
- data/docs/resources/mysql_conf.md.erb +14 -14
- data/docs/resources/mysql_session.md.erb +22 -10
- data/docs/resources/npm.md.erb +13 -13
- data/docs/resources/ntp_conf.md.erb +9 -9
- data/docs/resources/oneget.md.erb +11 -11
- data/docs/resources/oracledb_session.md.erb +53 -0
- data/docs/resources/os.md.erb +17 -17
- data/docs/resources/os_env.md.erb +12 -12
- data/docs/resources/package.md.erb +29 -16
- data/docs/resources/parse_config.md.erb +18 -18
- data/docs/resources/parse_config_file.md.erb +29 -23
- data/docs/resources/{etc_passwd.md.erb → passwd.md.erb} +17 -17
- data/docs/resources/pip.md.erb +15 -15
- data/docs/resources/port.md.erb +23 -23
- data/docs/resources/postgres_conf.md.erb +15 -13
- data/docs/resources/postgres_hba_conf.md.erb +104 -0
- data/docs/resources/postgres_ident_conf.md.erb +87 -0
- data/docs/resources/postgres_session.md.erb +28 -21
- data/docs/resources/powershell.md.erb +14 -14
- data/docs/resources/processes.md.erb +123 -0
- data/docs/resources/rabbitmq_config.md.erb +55 -0
- data/docs/resources/registry_key.md.erb +44 -21
- data/docs/resources/runit_service.md.erb +11 -11
- data/docs/resources/security_policy.md.erb +10 -10
- data/docs/resources/service.md.erb +18 -18
- data/docs/resources/{etc_shadow.md.erb → shadow.md.erb} +19 -19
- data/docs/resources/ssh_config.md.erb +13 -13
- data/docs/resources/sshd_config.md.erb +15 -15
- data/docs/resources/ssl.md.erb +13 -13
- data/docs/resources/sys_info.md.erb +10 -10
- data/docs/resources/systemd_service.md.erb +11 -11
- data/docs/resources/sysv_service.md.erb +11 -11
- data/docs/resources/upstart_service.md.erb +11 -11
- data/docs/resources/user.md.erb +20 -20
- data/docs/resources/users.md.erb +19 -19
- data/docs/resources/vbscript.md.erb +13 -13
- data/docs/resources/virtualization.md.erb +71 -0
- data/docs/resources/windows_feature.md.erb +10 -10
- data/docs/resources/windows_task.md.erb +103 -0
- data/docs/resources/wmi.md.erb +10 -10
- data/docs/resources/x509_certificate.md.erb +146 -0
- data/docs/resources/xinetd_conf.md.erb +17 -17
- data/docs/resources/xml.md.erb +75 -0
- data/docs/resources/yaml.md.erb +25 -11
- data/docs/resources/yum.md.erb +24 -16
- data/docs/resources/zfs_dataset.md.erb +63 -0
- data/docs/resources/zfs_pool.md.erb +57 -0
- data/docs/ruby_usage.md +50 -0
- data/docs/shared/matcher_cmp.md.erb +4 -6
- data/examples/inheritance/README.md +49 -3
- data/examples/inheritance/controls/example.rb +4 -1
- data/examples/inheritance/inspec.yml +3 -1
- data/examples/meta-profile/README.md +29 -3
- data/examples/meta-profile/controls/example.rb +10 -5
- data/examples/meta-profile/inspec.yml +4 -8
- data/examples/profile/README.md +1 -1
- data/examples/profile/controls/example.rb +0 -1
- data/examples/profile/controls/gordon.rb +0 -1
- data/examples/profile/inspec.yml +1 -1
- data/examples/profile-attribute/inspec.yml +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 +10 -2
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +284 -0
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-compliance/README.md +44 -15
- data/lib/bundles/inspec-compliance/api.rb +135 -29
- data/lib/bundles/inspec-compliance/cli.rb +128 -21
- data/lib/bundles/inspec-compliance/configuration.rb +8 -0
- data/lib/bundles/inspec-compliance/http.rb +26 -19
- data/lib/bundles/inspec-compliance/target.rb +50 -25
- data/lib/bundles/inspec-habitat/cli.rb +31 -0
- data/lib/bundles/inspec-habitat/log.rb +10 -0
- data/lib/bundles/inspec-habitat/profile.rb +372 -0
- data/lib/bundles/inspec-habitat.rb +12 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +0 -1
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +1 -1
- data/lib/bundles/inspec-supermarket/api.rb +7 -5
- data/lib/bundles/inspec-supermarket/cli.rb +2 -2
- data/lib/fetchers/git.rb +4 -2
- data/lib/fetchers/local.rb +4 -1
- data/lib/fetchers/url.rb +64 -10
- data/lib/inspec/archive/tar.rb +1 -1
- data/lib/inspec/backend.rb +26 -3
- data/lib/inspec/base_cli.rb +44 -7
- data/lib/inspec/cached_fetcher.rb +2 -2
- data/lib/inspec/cli.rb +34 -12
- data/lib/inspec/completions/fish.sh.erb +34 -0
- data/lib/inspec/control_eval_context.rb +0 -2
- data/lib/inspec/dependencies/cache.rb +0 -1
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dependencies/lockfile.rb +13 -6
- data/lib/inspec/dependencies/requirement.rb +6 -6
- data/lib/inspec/dependencies/resolver.rb +4 -4
- data/lib/inspec/dsl.rb +3 -5
- data/lib/inspec/env_printer.rb +9 -1
- data/lib/inspec/exceptions.rb +8 -0
- data/lib/inspec/fetcher.rb +1 -1
- data/lib/inspec/file_provider.rb +47 -11
- data/lib/inspec/library_eval_context.rb +1 -1
- data/lib/inspec/metadata.rb +62 -18
- data/lib/inspec/method_source.rb +24 -0
- data/lib/inspec/objects/attribute.rb +21 -0
- data/lib/inspec/objects/control.rb +21 -3
- data/lib/inspec/objects/each_loop.rb +2 -1
- data/lib/inspec/objects/list.rb +1 -1
- data/lib/inspec/objects/or_test.rb +17 -2
- data/lib/inspec/objects/tag.rb +27 -0
- data/lib/inspec/objects/test.rb +9 -8
- data/lib/inspec/objects.rb +1 -0
- data/lib/inspec/plugins/fetcher.rb +4 -5
- data/lib/inspec/plugins/resource.rb +1 -2
- data/lib/inspec/plugins/source_reader.rb +3 -3
- data/lib/inspec/plugins.rb +1 -1
- data/lib/inspec/polyfill.rb +0 -1
- data/lib/inspec/profile.rb +92 -23
- data/lib/inspec/profile_context.rb +1 -1
- data/lib/inspec/profile_vendor.rb +66 -0
- data/lib/inspec/resource.rb +29 -3
- data/lib/inspec/rspec_json_formatter.rb +672 -285
- data/lib/inspec/rule.rb +12 -16
- data/lib/inspec/runner.rb +26 -15
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/runtime_profile.rb +26 -0
- data/lib/inspec/schema.rb +185 -0
- data/lib/inspec/secrets/yaml.rb +8 -1
- data/lib/inspec/secrets.rb +1 -1
- data/lib/inspec/shell.rb +92 -22
- data/lib/inspec/source_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec.rb +1 -1
- data/lib/matchers/matchers.rb +67 -17
- data/lib/resources/aide_conf.rb +162 -0
- data/lib/resources/apache.rb +0 -1
- data/lib/resources/apache_conf.rb +3 -3
- data/lib/resources/apt.rb +2 -1
- data/lib/resources/audit_policy.rb +0 -1
- data/lib/resources/auditd_conf.rb +1 -2
- data/lib/resources/auditd_rules.rb +5 -5
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/bridge.rb +1 -1
- data/lib/resources/command.rb +5 -3
- data/lib/resources/crontab.rb +102 -0
- data/lib/resources/csv.rb +18 -1
- data/lib/resources/dh_params.rb +84 -0
- data/lib/resources/directory.rb +7 -3
- data/lib/resources/docker.rb +198 -0
- data/lib/resources/docker_container.rb +114 -0
- data/lib/resources/docker_image.rb +96 -0
- data/lib/resources/etc_group.rb +2 -3
- data/lib/resources/etc_hosts.rb +81 -0
- data/lib/resources/file.rb +88 -30
- data/lib/resources/gem.rb +26 -6
- data/lib/resources/groups.rb +4 -5
- data/lib/resources/grub_conf.rb +3 -4
- data/lib/resources/host.rb +175 -35
- data/lib/resources/http.rb +73 -0
- data/lib/resources/iis_app.rb +103 -0
- data/lib/resources/iis_site.rb +23 -0
- data/lib/resources/inetd_conf.rb +9 -4
- data/lib/resources/interface.rb +4 -3
- data/lib/resources/json.rb +37 -14
- data/lib/resources/kernel_module.rb +77 -10
- data/lib/resources/kernel_parameter.rb +0 -1
- data/lib/resources/key_rsa.rb +67 -0
- data/lib/resources/limits_conf.rb +3 -4
- data/lib/resources/login_def.rb +2 -3
- data/lib/resources/mount.rb +34 -4
- data/lib/resources/mssql_session.rb +81 -12
- data/lib/resources/mysql.rb +0 -1
- data/lib/resources/mysql_conf.rb +1 -2
- data/lib/resources/mysql_session.rb +18 -7
- data/lib/resources/nginx_conf.rb +95 -0
- data/lib/resources/ntp_conf.rb +2 -3
- data/lib/resources/oracledb_session.rb +138 -0
- data/lib/resources/os_env.rb +7 -5
- data/lib/resources/package.rb +70 -13
- data/lib/resources/packages.rb +111 -0
- data/lib/resources/parse_config.rb +3 -4
- data/lib/resources/passwd.rb +4 -5
- data/lib/resources/pip.rb +29 -21
- data/lib/resources/port.rb +133 -14
- data/lib/resources/postgres.rb +53 -43
- data/lib/resources/postgres_conf.rb +40 -13
- data/lib/resources/postgres_hba_conf.rb +101 -0
- data/lib/resources/postgres_ident_conf.rb +79 -0
- data/lib/resources/postgres_session.rb +28 -20
- data/lib/resources/powershell.rb +2 -2
- data/lib/resources/processes.rb +61 -26
- data/lib/resources/rabbitmq_conf.rb +53 -0
- data/lib/resources/registry_key.rb +34 -11
- data/lib/resources/security_policy.rb +2 -2
- data/lib/resources/service.rb +17 -7
- data/lib/resources/ssh_conf.rb +17 -6
- data/lib/resources/ssl.rb +3 -4
- data/lib/resources/sys_info.rb +1 -1
- data/lib/resources/toml.rb +26 -0
- data/lib/resources/users.rb +41 -41
- data/lib/resources/virtualization.rb +252 -0
- data/lib/resources/windows_task.rb +106 -0
- data/lib/resources/x509_certificate.rb +143 -0
- data/lib/resources/xinetd.rb +18 -2
- data/lib/resources/xml.rb +27 -0
- data/lib/resources/yaml.rb +10 -2
- data/lib/resources/yum.rb +25 -7
- data/lib/resources/zfs_dataset.rb +60 -0
- data/lib/resources/zfs_pool.rb +49 -0
- data/lib/source_readers/flat.rb +2 -1
- data/lib/source_readers/inspec.rb +30 -11
- data/lib/utils/command_wrapper.rb +3 -3
- data/lib/utils/database_helpers.rb +77 -0
- data/lib/utils/erlang_parser.rb +192 -0
- data/lib/utils/filter.rb +2 -1
- data/lib/utils/filter_array.rb +0 -1
- data/lib/utils/find_files.rb +1 -2
- data/lib/utils/latest_version.rb +21 -0
- data/lib/utils/nginx_parser.rb +76 -0
- data/lib/utils/object_traversal.rb +5 -4
- data/lib/utils/parser.rb +23 -4
- data/lib/utils/plugin_registry.rb +3 -3
- data/lib/utils/simpleconfig.rb +25 -8
- data/lib/utils/spdx.rb +13 -0
- data/lib/utils/spdx.txt +344 -0
- metadata +168 -22
- data/docs/cli.md +0 -342
- data/docs/resources/process.md.erb +0 -73
- /data/docs/{plugin_kitchen_inspec.html.md → plugin_kitchen_inspec.md} +0 -0
data/lib/fetchers/git.rb
CHANGED
|
@@ -24,7 +24,7 @@ module Fetchers
|
|
|
24
24
|
# you got to this file during debugging, you may want to look at the
|
|
25
25
|
# omnibus source for hints.
|
|
26
26
|
#
|
|
27
|
-
class Git < Inspec.fetcher(1)
|
|
27
|
+
class Git < Inspec.fetcher(1) # rubocop:disable ClassLength
|
|
28
28
|
name 'git'
|
|
29
29
|
priority 200
|
|
30
30
|
|
|
@@ -44,6 +44,8 @@ module Fetchers
|
|
|
44
44
|
|
|
45
45
|
def fetch(dir)
|
|
46
46
|
@repo_directory = dir
|
|
47
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
48
|
+
|
|
47
49
|
if cloned?
|
|
48
50
|
checkout
|
|
49
51
|
else
|
|
@@ -86,7 +88,7 @@ module Fetchers
|
|
|
86
88
|
cmd = shellout("git ls-remote \"#{@remote_url}\" \"#{ref_name}*\"")
|
|
87
89
|
ref = parse_ls_remote(cmd.stdout, ref_name)
|
|
88
90
|
if !ref
|
|
89
|
-
|
|
91
|
+
raise "Unable to resolve #{ref_name} to a specific git commit for #{@remote_url}"
|
|
90
92
|
end
|
|
91
93
|
ref
|
|
92
94
|
end
|
data/lib/fetchers/local.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
# author: Dominik Richter
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
4
|
|
|
5
|
+
require 'openssl'
|
|
6
|
+
|
|
5
7
|
module Fetchers
|
|
6
8
|
class Local < Inspec.fetcher(1)
|
|
7
9
|
name 'local'
|
|
@@ -65,7 +67,8 @@ module Fetchers
|
|
|
65
67
|
|
|
66
68
|
def sha256
|
|
67
69
|
return nil if File.directory?(@target)
|
|
68
|
-
@archive_shasum ||=
|
|
70
|
+
@archive_shasum ||=
|
|
71
|
+
OpenSSL::Digest::SHA256.digest(File.read(@target)).unpack('H*')[0]
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
def resolved_source
|
data/lib/fetchers/url.rb
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
4
|
|
|
5
5
|
require 'uri'
|
|
6
|
-
require '
|
|
6
|
+
require 'openssl'
|
|
7
7
|
require 'tempfile'
|
|
8
8
|
require 'open-uri'
|
|
9
9
|
|
|
10
10
|
module Fetchers
|
|
11
|
-
class Url < Inspec.fetcher(1)
|
|
11
|
+
class Url < Inspec.fetcher(1) # rubocop:disable Metrics/ClassLength
|
|
12
12
|
MIME_TYPES = {
|
|
13
13
|
'application/x-zip-compressed' => '.zip',
|
|
14
14
|
'application/zip' => '.zip',
|
|
@@ -37,8 +37,8 @@ module Fetchers
|
|
|
37
37
|
nil
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
# Transforms a browser github url to github tar url
|
|
41
|
-
# We distinguish between three different Github URL types:
|
|
40
|
+
# Transforms a browser github/bitbucket url to github/bitbucket tar url
|
|
41
|
+
# We distinguish between three different Github/Bitbucket URL types:
|
|
42
42
|
# - Master URL
|
|
43
43
|
# - Branch URL
|
|
44
44
|
# - Commit URL
|
|
@@ -46,22 +46,39 @@ module Fetchers
|
|
|
46
46
|
# master url:
|
|
47
47
|
# https://github.com/nathenharvey/tmp_compliance_profile/ is transformed to
|
|
48
48
|
# https://github.com/nathenharvey/tmp_compliance_profile/archive/master.tar.gz
|
|
49
|
+
# https://bitbucket.org/username/repo is transformed to
|
|
50
|
+
# https://bitbucket.org/username/repo/get/master.tar.gz
|
|
49
51
|
#
|
|
50
|
-
#
|
|
52
|
+
# branch:
|
|
51
53
|
# https://github.com/hardening-io/tests-os-hardening/tree/2.0 is transformed to
|
|
52
54
|
# https://github.com/hardening-io/tests-os-hardening/archive/2.0.tar.gz
|
|
55
|
+
# https://bitbucket.org/username/repo/branch/branchname is transformed to
|
|
56
|
+
# https://bitbucket.org/username/repo/get/newbranch.tar.gz
|
|
53
57
|
#
|
|
54
|
-
#
|
|
58
|
+
# commit:
|
|
55
59
|
# https://github.com/hardening-io/tests-os-hardening/tree/48bd4388ddffde68badd83aefa654e7af3231876
|
|
56
60
|
# is transformed to
|
|
57
61
|
# https://github.com/hardening-io/tests-os-hardening/archive/48bd4388ddffde68badd83aefa654e7af3231876.tar.gz
|
|
62
|
+
# https://bitbucket.org/username/repo/commits/95ce1f83d5bbe9eec34c5973f6894617e8d6d8cc is transformed to
|
|
63
|
+
# https://bitbucket.org/username/repo/get/95ce1f83d5bbe9eec34c5973f6894617e8d6d8cc.tar.gz
|
|
64
|
+
|
|
58
65
|
GITHUB_URL_REGEX = %r{^https?://(www\.)?github\.com/(?<user>[\w-]+)/(?<repo>[\w-]+)(\.git)?(/)?$}
|
|
59
66
|
GITHUB_URL_WITH_TREE_REGEX = %r{^https?://(www\.)?github\.com/(?<user>[\w-]+)/(?<repo>[\w-]+)/tree/(?<commit>[\w\.]+)(/)?$}
|
|
67
|
+
BITBUCKET_URL_REGEX = %r{^https?://(www\.)?bitbucket\.org/(?<user>[\w-]+)/(?<repo>[\w-]+)(\.git)?(/)?$}
|
|
68
|
+
BITBUCKET_URL_BRANCH_REGEX = %r{^https?://(www\.)?bitbucket\.org/(?<user>[\w-]+)/(?<repo>[\w-]+)/branch/(?<branch>[\w\.]+)(/)?$}
|
|
69
|
+
BITBUCKET_URL_COMMIT_REGEX = %r{^https?://(www\.)?bitbucket\.org/(?<user>[\w-]+)/(?<repo>[\w-]+)/commits/(?<commit>[\w\.]+)(/)?$}
|
|
70
|
+
|
|
60
71
|
def self.transform(target)
|
|
61
72
|
transformed_target = if m = GITHUB_URL_REGEX.match(target) # rubocop:disable Lint/AssignmentInCondition
|
|
62
73
|
"https://github.com/#{m[:user]}/#{m[:repo]}/archive/master.tar.gz"
|
|
63
74
|
elsif m = GITHUB_URL_WITH_TREE_REGEX.match(target) # rubocop:disable Lint/AssignmentInCondition
|
|
64
75
|
"https://github.com/#{m[:user]}/#{m[:repo]}/archive/#{m[:commit]}.tar.gz"
|
|
76
|
+
elsif m = BITBUCKET_URL_REGEX.match(target) # rubocop:disable Lint/AssignmentInCondition
|
|
77
|
+
"https://bitbucket.org/#{m[:user]}/#{m[:repo]}/get/master.tar.gz"
|
|
78
|
+
elsif m = BITBUCKET_URL_BRANCH_REGEX.match(target) # rubocop:disable Lint/AssignmentInCondition
|
|
79
|
+
"https://bitbucket.org/#{m[:user]}/#{m[:repo]}/get/#{m[:branch]}.tar.gz"
|
|
80
|
+
elsif m = BITBUCKET_URL_COMMIT_REGEX.match(target) # rubocop:disable Lint/AssignmentInCondition
|
|
81
|
+
"https://bitbucket.org/#{m[:user]}/#{m[:repo]}/get/#{m[:commit]}.tar.gz"
|
|
65
82
|
end
|
|
66
83
|
|
|
67
84
|
if transformed_target
|
|
@@ -79,6 +96,8 @@ module Fetchers
|
|
|
79
96
|
@insecure = opts['insecure']
|
|
80
97
|
@token = opts['token']
|
|
81
98
|
@config = opts
|
|
99
|
+
@archive_path = nil
|
|
100
|
+
@temp_archive_path = nil
|
|
82
101
|
end
|
|
83
102
|
|
|
84
103
|
def fetch(path)
|
|
@@ -101,7 +120,7 @@ module Fetchers
|
|
|
101
120
|
|
|
102
121
|
def sha256
|
|
103
122
|
file = @archive_path || temp_archive_path
|
|
104
|
-
Digest::SHA256.
|
|
123
|
+
OpenSSL::Digest::SHA256.digest(File.read(file)).unpack('H*')[0]
|
|
105
124
|
end
|
|
106
125
|
|
|
107
126
|
def file_type_from_remote(remote)
|
|
@@ -124,9 +143,6 @@ module Fetchers
|
|
|
124
143
|
def download_archive_to_temp
|
|
125
144
|
return @temp_archive_path if ! @temp_archive_path.nil?
|
|
126
145
|
Inspec::Log.debug("Fetching URL: #{@target}")
|
|
127
|
-
http_opts = {}
|
|
128
|
-
http_opts['ssl_verify_mode'.to_sym] = OpenSSL::SSL::VERIFY_NONE if @insecure
|
|
129
|
-
http_opts['Authorization'] = "Bearer #{@token}" if @token
|
|
130
146
|
remote = open(@target, http_opts)
|
|
131
147
|
@archive_type = file_type_from_remote(remote) # side effect :(
|
|
132
148
|
archive = Tempfile.new(['inspec-dl-', @archive_type])
|
|
@@ -141,10 +157,48 @@ module Fetchers
|
|
|
141
157
|
def download_archive(path)
|
|
142
158
|
download_archive_to_temp
|
|
143
159
|
final_path = "#{path}#{@archive_type}"
|
|
160
|
+
FileUtils.mkdir_p(File.dirname(final_path))
|
|
144
161
|
FileUtils.mv(temp_archive_path, final_path)
|
|
145
162
|
Inspec::Log.debug("Fetched archive moved to: #{final_path}")
|
|
146
163
|
@temp_archive_path = nil
|
|
147
164
|
final_path
|
|
148
165
|
end
|
|
166
|
+
|
|
167
|
+
def http_opts
|
|
168
|
+
opts = {}
|
|
169
|
+
opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE if @insecure
|
|
170
|
+
|
|
171
|
+
if @config['server_type'] == 'automate'
|
|
172
|
+
opts['chef-delivery-enterprise'] = @config['automate']['ent']
|
|
173
|
+
if @config['automate']['token_type'] == 'dctoken'
|
|
174
|
+
opts['x-data-collector-token'] = @config['token']
|
|
175
|
+
else
|
|
176
|
+
opts['chef-delivery-user'] = @config['user']
|
|
177
|
+
opts['chef-delivery-token'] = @config['token']
|
|
178
|
+
end
|
|
179
|
+
elsif @token
|
|
180
|
+
opts['Authorization'] = "Bearer #{@token}"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Do not send any headers that have nil values.
|
|
184
|
+
# Net::HTTP does not gracefully handle this situation.
|
|
185
|
+
check_for_missing_values!(opts)
|
|
186
|
+
|
|
187
|
+
opts
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def check_for_missing_values!(opts)
|
|
191
|
+
keys_missing_values = opts.keys.delete_if do |k|
|
|
192
|
+
if opts[k].nil?
|
|
193
|
+
false
|
|
194
|
+
elsif opts[k].respond_to?(:empty?) && opts[k].empty?
|
|
195
|
+
false
|
|
196
|
+
else
|
|
197
|
+
true
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
raise 'Unable to fetch profile - the following HTTP headers have no value: ' \
|
|
201
|
+
"#{keys_missing_values.join(', ')}" unless keys_missing_values.empty?
|
|
202
|
+
end
|
|
149
203
|
end
|
|
150
204
|
end
|
data/lib/inspec/archive/tar.rb
CHANGED
data/lib/inspec/backend.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# copyright: 2015, Dominik Richter
|
|
3
|
-
# license: All rights reserved
|
|
4
3
|
# author: Dominik Richter
|
|
5
4
|
# author: Christoph Hartmann
|
|
6
5
|
|
|
@@ -8,6 +7,27 @@ require 'train'
|
|
|
8
7
|
|
|
9
8
|
module Inspec
|
|
10
9
|
module Backend
|
|
10
|
+
module Base
|
|
11
|
+
attr_accessor :profile
|
|
12
|
+
|
|
13
|
+
# Provide a shorthand to retrieve the inspec version from within a profile
|
|
14
|
+
#
|
|
15
|
+
# @return [String] inspec version
|
|
16
|
+
def version
|
|
17
|
+
Inspec::VERSION
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Ruby internal for printing a nice name for this class
|
|
21
|
+
def to_s
|
|
22
|
+
'Inspec::Backend::Class'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Ruby internal for pretty-printing a summary for this class
|
|
26
|
+
def inspect
|
|
27
|
+
"Inspec::Backend::Class @transport=#{backend.class}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
11
31
|
# Create the transport backend with aggregated resources.
|
|
12
32
|
#
|
|
13
33
|
# @param [Hash] config for the transport backend
|
|
@@ -17,18 +37,21 @@ module Inspec
|
|
|
17
37
|
name = Train.validate_backend(conf)
|
|
18
38
|
transport = Train.create(name, conf)
|
|
19
39
|
if transport.nil?
|
|
20
|
-
|
|
40
|
+
raise "Can't find transport backend '#{name}'."
|
|
21
41
|
end
|
|
22
42
|
|
|
23
43
|
connection = transport.connection
|
|
24
44
|
if connection.nil?
|
|
25
|
-
|
|
45
|
+
raise "Can't connect to transport backend '#{name}'."
|
|
26
46
|
end
|
|
27
47
|
|
|
28
48
|
cls = Class.new do
|
|
49
|
+
include Base
|
|
50
|
+
|
|
29
51
|
define_method :backend do
|
|
30
52
|
connection
|
|
31
53
|
end
|
|
54
|
+
|
|
32
55
|
Inspec::Resource.registry.each do |id, r|
|
|
33
56
|
define_method id.to_sym do |*args|
|
|
34
57
|
r.new(self, id.to_s, *args)
|
data/lib/inspec/base_cli.rb
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
require 'thor'
|
|
6
6
|
require 'inspec/log'
|
|
7
|
+
require 'inspec/profile_vendor'
|
|
7
8
|
|
|
8
9
|
module Inspec
|
|
9
10
|
class BaseCLI < Thor # rubocop:disable Metrics/ClassLength
|
|
@@ -18,7 +19,7 @@ module Inspec
|
|
|
18
19
|
desc: 'Specify the login port for a remote scan.'
|
|
19
20
|
option :user, type: :string,
|
|
20
21
|
desc: 'The login user for a remote scan.'
|
|
21
|
-
option :password, type: :string,
|
|
22
|
+
option :password, type: :string, lazy_default: -1,
|
|
22
23
|
desc: 'Login password for a remote scan, if required.'
|
|
23
24
|
option :key_files, aliases: :i, type: :array,
|
|
24
25
|
desc: 'Login key or certificate file for a remote scan.'
|
|
@@ -26,20 +27,24 @@ module Inspec
|
|
|
26
27
|
desc: 'Login path to use when connecting to the target (WinRM).'
|
|
27
28
|
option :sudo, type: :boolean,
|
|
28
29
|
desc: 'Run scans with sudo. Only activates on Unix and non-root user.'
|
|
29
|
-
option :sudo_password, type: :string,
|
|
30
|
+
option :sudo_password, type: :string, lazy_default: -1,
|
|
30
31
|
desc: 'Specify a sudo password, if it is required.'
|
|
31
32
|
option :sudo_options, type: :string,
|
|
32
33
|
desc: 'Additional sudo options for a remote scan.'
|
|
33
34
|
option :sudo_command, type: :string,
|
|
34
35
|
desc: 'Alternate command for sudo.'
|
|
36
|
+
option :shell, type: :boolean,
|
|
37
|
+
desc: 'Run scans in a subshell. Only activates on Unix.'
|
|
38
|
+
option :shell_options, type: :string,
|
|
39
|
+
desc: 'Additional shell options.'
|
|
40
|
+
option :shell_command, type: :string,
|
|
41
|
+
desc: 'Specify a particular shell to use.'
|
|
35
42
|
option :ssl, type: :boolean,
|
|
36
43
|
desc: 'Use SSL for transport layer encryption (WinRM).'
|
|
37
44
|
option :self_signed, type: :boolean,
|
|
38
45
|
desc: 'Allow remote scans with self-signed certificates (WinRM).'
|
|
39
46
|
option :json_config, type: :string,
|
|
40
47
|
desc: 'Read configuration from JSON file (`-` reads from stdin).'
|
|
41
|
-
option :log_level, aliases: :l, type: :string,
|
|
42
|
-
desc: 'Set the log level: info (default), debug, warn, error'
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
def self.profile_options
|
|
@@ -53,7 +58,7 @@ module Inspec
|
|
|
53
58
|
option :controls, type: :array,
|
|
54
59
|
desc: 'A list of controls to run. Ignore all other tests.'
|
|
55
60
|
option :format, type: :string,
|
|
56
|
-
desc: 'Which formatter to use: cli, progress, documentation, json, json-min'
|
|
61
|
+
desc: 'Which formatter to use: cli, progress, documentation, json, json-min, junit'
|
|
57
62
|
option :color, type: :boolean, default: true,
|
|
58
63
|
desc: 'Use colors in output.'
|
|
59
64
|
option :attrs, type: :array,
|
|
@@ -76,7 +81,7 @@ module Inspec
|
|
|
76
81
|
runner = Inspec::Runner.new(o)
|
|
77
82
|
targets.each { |target| runner.add_target(target) }
|
|
78
83
|
exit runner.run
|
|
79
|
-
rescue RuntimeError, Train::UserError => e
|
|
84
|
+
rescue ArgumentError, RuntimeError, Train::UserError => e
|
|
80
85
|
$stderr.puts e.message
|
|
81
86
|
exit 1
|
|
82
87
|
end
|
|
@@ -95,6 +100,23 @@ module Inspec
|
|
|
95
100
|
end
|
|
96
101
|
|
|
97
102
|
def opts
|
|
103
|
+
o = merged_opts
|
|
104
|
+
|
|
105
|
+
# Due to limitations in Thor it is not possible to set an argument to be
|
|
106
|
+
# both optional and its value to be mandatory. E.g. the user supplying
|
|
107
|
+
# the --password argument is optional and not always required, but
|
|
108
|
+
# whenever it is used, it requires a value. Handle options that were
|
|
109
|
+
# defined above and require a value here:
|
|
110
|
+
%w{password sudo-password}.each do |v|
|
|
111
|
+
id = v.tr('-', '_').to_sym
|
|
112
|
+
next unless o[id] == -1
|
|
113
|
+
raise ArgumentError, "Please provide a value for --#{v}. For example: --#{v}=hello."
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
o
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def merged_opts
|
|
98
120
|
# argv overrides json
|
|
99
121
|
Thor::CoreExt::HashWithIndifferentAccess.new(options_json.merge(options))
|
|
100
122
|
end
|
|
@@ -138,10 +160,25 @@ module Inspec
|
|
|
138
160
|
$stderr.puts exception.message
|
|
139
161
|
exit(1)
|
|
140
162
|
else
|
|
141
|
-
raise exception
|
|
163
|
+
raise exception
|
|
142
164
|
end
|
|
143
165
|
end
|
|
144
166
|
|
|
167
|
+
def vendor_deps(path, opts)
|
|
168
|
+
profile_path = path || Dir.pwd
|
|
169
|
+
profile_vendor = Inspec::ProfileVendor.new(profile_path)
|
|
170
|
+
|
|
171
|
+
if (profile_vendor.cache_path.exist? || profile_vendor.lockfile.exist?) && !opts[:overwrite]
|
|
172
|
+
puts 'Profile is already vendored. Use --overwrite.'
|
|
173
|
+
return false
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
profile_vendor.vendor!
|
|
177
|
+
puts "Dependencies for profile #{profile_path} successfully vendored to #{profile_vendor.cache_path}"
|
|
178
|
+
rescue StandardError => e
|
|
179
|
+
pretty_handle_exception(e)
|
|
180
|
+
end
|
|
181
|
+
|
|
145
182
|
def configure_logger(o)
|
|
146
183
|
#
|
|
147
184
|
# TODO(ssd): This is a big gross, but this configures the
|
|
@@ -12,7 +12,7 @@ module Inspec
|
|
|
12
12
|
@fetcher = Inspec::Fetcher.resolve(target)
|
|
13
13
|
|
|
14
14
|
if @fetcher.nil?
|
|
15
|
-
|
|
15
|
+
raise("Could not fetch inspec profile in #{target.inspect}.")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
@cache = cache
|
|
@@ -50,7 +50,7 @@ module Inspec
|
|
|
50
50
|
def assert_cache_sanity!
|
|
51
51
|
if target.respond_to?(:key?) && target.key?(:sha256)
|
|
52
52
|
if fetcher.resolved_source[:sha256] != target[:sha256]
|
|
53
|
-
|
|
53
|
+
raise <<EOF
|
|
54
54
|
The remote source #{fetcher} no longer has the requested content:
|
|
55
55
|
|
|
56
56
|
Request Content Hash: #{target[:sha256]}
|
data/lib/inspec/cli.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# encoding: utf-8
|
|
3
|
-
# Copyright 2015 Dominik Richter
|
|
3
|
+
# Copyright 2015 Dominik Richter
|
|
4
4
|
# author: Dominik Richter
|
|
5
5
|
# author: Christoph Hartmann
|
|
6
6
|
|
|
@@ -9,10 +9,12 @@ require 'thor'
|
|
|
9
9
|
require 'json'
|
|
10
10
|
require 'pp'
|
|
11
11
|
require 'utils/json_log'
|
|
12
|
+
require 'utils/latest_version'
|
|
12
13
|
require 'inspec/base_cli'
|
|
13
14
|
require 'inspec/plugins'
|
|
14
15
|
require 'inspec/runner_mock'
|
|
15
16
|
require 'inspec/env_printer'
|
|
17
|
+
require 'inspec/schema'
|
|
16
18
|
|
|
17
19
|
class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
18
20
|
class_option :log_level, aliases: :l, type: :string,
|
|
@@ -34,6 +36,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
34
36
|
diagnose
|
|
35
37
|
o = opts.dup
|
|
36
38
|
o[:ignore_supports] = true
|
|
39
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
|
37
40
|
|
|
38
41
|
profile = Inspec::Profile.for_target(target, o)
|
|
39
42
|
dst = o[:output].to_s
|
|
@@ -58,8 +61,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
58
61
|
def check(path) # rubocop:disable Metrics/AbcSize
|
|
59
62
|
diagnose
|
|
60
63
|
o = opts.dup
|
|
61
|
-
# configure_logger(o) # we do not need a logger for check yet
|
|
62
64
|
o[:ignore_supports] = true # we check for integrity only
|
|
65
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
|
63
66
|
|
|
64
67
|
# run check
|
|
65
68
|
profile = Inspec::Profile.for_target(path, o)
|
|
@@ -103,14 +106,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
103
106
|
pretty_handle_exception(e)
|
|
104
107
|
end
|
|
105
108
|
|
|
106
|
-
desc 'vendor', 'Download all dependencies and generate a lockfile'
|
|
109
|
+
desc 'vendor PATH', 'Download all dependencies and generate a lockfile in a `vendor` directory'
|
|
110
|
+
option :overwrite, type: :boolean, default: false,
|
|
111
|
+
desc: 'Overwrite existing vendored dependencies and lockfile.'
|
|
107
112
|
def vendor(path = nil)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
lockfile = profile.generate_lockfile
|
|
111
|
-
File.write('inspec.lock', lockfile.to_yaml)
|
|
112
|
-
rescue StandardError => e
|
|
113
|
-
pretty_handle_exception(e)
|
|
113
|
+
o = opts.dup
|
|
114
|
+
vendor_deps(path, o)
|
|
114
115
|
end
|
|
115
116
|
|
|
116
117
|
desc 'archive PATH', 'archive a profile to tar.gz (default) or zip'
|
|
@@ -131,12 +132,13 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
131
132
|
o = opts.dup
|
|
132
133
|
o[:logger] = Logger.new(STDOUT)
|
|
133
134
|
o[:logger].level = get_log_level(o.log_level)
|
|
135
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
|
134
136
|
|
|
135
137
|
profile = Inspec::Profile.for_target(path, o)
|
|
136
138
|
result = profile.check
|
|
137
139
|
|
|
138
140
|
if result && !opts[:ignore_errors] == false
|
|
139
|
-
|
|
141
|
+
o[:logger].info 'Profile check failed. Please fix the profile before generating an archive.'
|
|
140
142
|
return exit 1
|
|
141
143
|
end
|
|
142
144
|
|
|
@@ -184,7 +186,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
184
186
|
option :command, aliases: :c,
|
|
185
187
|
desc: 'A single command string to run instead of launching the shell'
|
|
186
188
|
option :format, type: :string, default: nil, hide: true,
|
|
187
|
-
desc: 'Which formatter to use: cli, progress, documentation, json, json-min'
|
|
189
|
+
desc: 'Which formatter to use: cli, progress, documentation, json, json-min, junit'
|
|
188
190
|
def shell_func
|
|
189
191
|
diagnose
|
|
190
192
|
o = opts.dup
|
|
@@ -220,10 +222,30 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
|
220
222
|
pretty_handle_exception(e)
|
|
221
223
|
end
|
|
222
224
|
|
|
225
|
+
desc 'schema NAME', 'print the JSON schema', hide: true
|
|
226
|
+
def schema(name)
|
|
227
|
+
puts Inspec::Schema.json(name)
|
|
228
|
+
rescue StandardError => e
|
|
229
|
+
puts e
|
|
230
|
+
puts "Valid schemas are #{Inspec::Schema.names.join(', ')}"
|
|
231
|
+
end
|
|
232
|
+
|
|
223
233
|
desc 'version', 'prints the version of this tool'
|
|
234
|
+
option :format, type: :string
|
|
224
235
|
def version
|
|
225
|
-
|
|
236
|
+
if opts['format'] == 'json'
|
|
237
|
+
v = { version: Inspec::VERSION }
|
|
238
|
+
puts v.to_json
|
|
239
|
+
else
|
|
240
|
+
puts Inspec::VERSION
|
|
241
|
+
# display outdated version
|
|
242
|
+
latest = LatestInSpecVersion.new.latest
|
|
243
|
+
if Gem::Version.new(Inspec::VERSION) < Gem::Version.new(latest)
|
|
244
|
+
puts "\nYour version of InSpec is out of date! The latest version is #{latest}."
|
|
245
|
+
end
|
|
246
|
+
end
|
|
226
247
|
end
|
|
248
|
+
map %w{-v --version} => :version
|
|
227
249
|
|
|
228
250
|
private
|
|
229
251
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function __fish_inspec_no_command --description 'Test if inspec has yet to be given the main command'
|
|
2
|
+
set -l cmd (commandline -opc)
|
|
3
|
+
test (count $cmd) -eq 1
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
function __fish_inspec_using_command
|
|
7
|
+
set -l cmd (commandline -opc)
|
|
8
|
+
set -q cmd[2]; and test "$argv[1]" = $cmd[2]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
function __fish_inspec_using_command_and_no_subcommand
|
|
12
|
+
set -l cmd (commandline -opc)
|
|
13
|
+
test (count $cmd) -eq 2; and test "$argv[1]" = "$cmd[2]"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
function __fish_inspec_using_subcommand --argument-names cmd_main cmd_sub
|
|
17
|
+
set -l cmd (commandline -opc)
|
|
18
|
+
set -q cmd[3]; and test "$cmd_main" = $cmd[2] -a "$cmd_sub" = $cmd[3]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
<% top_level_commands_with_descriptions.each do |command_and_description| %>
|
|
22
|
+
<% command, description = command_and_description.split(':') %>
|
|
23
|
+
<% description.gsub!(/\\/, '') %>
|
|
24
|
+
# <%= command %> commands
|
|
25
|
+
complete -c inspec -f -n '__fish_inspec_no_command' -a <%= command %> -d "<%= description %>"
|
|
26
|
+
# <%= command %> help
|
|
27
|
+
complete -c inspec -f -n '__fish_inspec_using_command help' -a <%= command %> -d "<%= description %>"
|
|
28
|
+
|
|
29
|
+
<% (subcommands_with_commands_and_descriptions[command] || []).each do |command_and_description| %>
|
|
30
|
+
<% subcommand, description = command_and_description.split(':') %>
|
|
31
|
+
<% description.gsub!(/\\/, '') %>
|
|
32
|
+
complete -c inspec -f -n '__fish_inspec_using_command_and_no_subcommand <%= command %>' -a <%= subcommand %> -d "<%= description %>"
|
|
33
|
+
<% end %>
|
|
34
|
+
<% end %>
|
|
@@ -35,8 +35,6 @@ module Inspec
|
|
|
35
35
|
# @param profile_context [Inspec::ProfileContext]
|
|
36
36
|
# @param outer_dsl [OuterDSLClass]
|
|
37
37
|
# @return [ProfileContextClass]
|
|
38
|
-
#
|
|
39
|
-
# rubocop:disable Lint/NestedMethodDefinition
|
|
40
38
|
def self.create(profile_context, resources_dsl) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
41
39
|
rule_class = rule_context(resources_dsl)
|
|
42
40
|
profile_context_owner = profile_context
|
|
@@ -14,9 +14,9 @@ module Inspec
|
|
|
14
14
|
# @param cwd [String] Current working directory for relative path includes
|
|
15
15
|
# @param vendor_path [String] Path to the vendor directory
|
|
16
16
|
#
|
|
17
|
-
def self.from_lockfile(lockfile, cwd, cache, backend)
|
|
17
|
+
def self.from_lockfile(lockfile, cwd, cache, backend, opts = {})
|
|
18
18
|
dep_tree = lockfile.deps.map do |dep|
|
|
19
|
-
Inspec::Requirement.from_lock_entry(dep, cwd, cache, backend)
|
|
19
|
+
Inspec::Requirement.from_lock_entry(dep, cwd, cache, backend, opts)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
dep_list = flatten_dep_tree(dep_tree)
|
|
@@ -15,17 +15,23 @@ module Inspec
|
|
|
15
15
|
new(lockfile_content)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def self.
|
|
19
|
-
parsed_content = YAML.load(
|
|
18
|
+
def self.from_content(content)
|
|
19
|
+
parsed_content = YAML.load(content)
|
|
20
20
|
version = parsed_content['lockfile_version']
|
|
21
|
-
|
|
21
|
+
raise "No lockfile_version set in #{path}!" if version.nil?
|
|
22
22
|
validate_lockfile_version!(version.to_i)
|
|
23
23
|
new(parsed_content)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.from_file(path)
|
|
27
|
+
content = File.read(path)
|
|
28
|
+
from_content(content)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# rubocop:disable Style/GuardClause
|
|
26
32
|
def self.validate_lockfile_version!(version)
|
|
27
33
|
if version < MINIMUM_SUPPORTED_VERSION
|
|
28
|
-
|
|
34
|
+
raise <<EOF
|
|
29
35
|
This lockfile specifies a lockfile_version of #{version} which is
|
|
30
36
|
lower than the minimum supported version #{MINIMUM_SUPPORTED_VERSION}.
|
|
31
37
|
|
|
@@ -34,7 +40,7 @@ Please create a new lockfile for this project by running:
|
|
|
34
40
|
inspec vendor
|
|
35
41
|
EOF
|
|
36
42
|
elsif version > CURRENT_LOCKFILE_VERSION
|
|
37
|
-
|
|
43
|
+
raise <<EOF
|
|
38
44
|
This lockfile claims to be version #{version} which is greater than
|
|
39
45
|
the most recent lockfile version(#{CURRENT_LOCKFILE_VERSION}).
|
|
40
46
|
|
|
@@ -43,6 +49,7 @@ used to create the lockfile.
|
|
|
43
49
|
EOF
|
|
44
50
|
end
|
|
45
51
|
end
|
|
52
|
+
# rubocop:enable Style/GuardClause
|
|
46
53
|
|
|
47
54
|
attr_reader :version, :deps
|
|
48
55
|
def initialize(lockfile_content_hash)
|
|
@@ -75,7 +82,7 @@ EOF
|
|
|
75
82
|
else
|
|
76
83
|
# If we've gotten here, there is likely a mistake in the
|
|
77
84
|
# lockfile version validation in the constructor.
|
|
78
|
-
|
|
85
|
+
raise "No lockfile parser for version #{version}"
|
|
79
86
|
end
|
|
80
87
|
end
|
|
81
88
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
require 'inspec/cached_fetcher'
|
|
3
3
|
require 'inspec/dependencies/dependency_set'
|
|
4
|
-
require 'digest'
|
|
5
4
|
|
|
6
5
|
module Inspec
|
|
7
6
|
#
|
|
@@ -10,20 +9,20 @@ module Inspec
|
|
|
10
9
|
#
|
|
11
10
|
class Requirement
|
|
12
11
|
def self.from_metadata(dep, cache, opts)
|
|
13
|
-
|
|
12
|
+
raise 'Cannot load empty dependency.' if dep.nil? || dep.empty?
|
|
14
13
|
new(dep[:name], dep[:version], cache, opts[:cwd], opts.merge(dep))
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
def self.from_lock_entry(entry, cwd, cache, backend)
|
|
16
|
+
def self.from_lock_entry(entry, cwd, cache, backend, opts = {})
|
|
18
17
|
req = new(entry[:name],
|
|
19
18
|
entry[:version_constraints],
|
|
20
19
|
cache,
|
|
21
20
|
cwd,
|
|
22
|
-
entry[:resolved_source].merge(backend: backend))
|
|
21
|
+
entry[:resolved_source].merge(backend: backend).merge(opts))
|
|
23
22
|
|
|
24
23
|
locked_deps = []
|
|
25
24
|
Array(entry[:dependencies]).each do |dep_entry|
|
|
26
|
-
locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, cache, backend)
|
|
25
|
+
locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, cache, backend, opts)
|
|
27
26
|
end
|
|
28
27
|
req.lock_deps(locked_deps)
|
|
29
28
|
req
|
|
@@ -85,6 +84,7 @@ module Inspec
|
|
|
85
84
|
@fetcher ||= Inspec::CachedFetcher.new(opts, @cache)
|
|
86
85
|
end
|
|
87
86
|
|
|
87
|
+
# load dependencies of the dependency
|
|
88
88
|
def dependencies
|
|
89
89
|
@dependencies ||= profile.metadata.dependencies.map do |r|
|
|
90
90
|
Inspec::Requirement.from_metadata(r, @cache, cwd: @cwd, backend: @backend)
|
|
@@ -95,9 +95,9 @@ module Inspec
|
|
|
95
95
|
name
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
# load the profile for the requirement
|
|
98
99
|
def profile
|
|
99
100
|
return @profile if ! @profile.nil?
|
|
100
|
-
|
|
101
101
|
opts = @opts.dup
|
|
102
102
|
opts[:backend] = @backend
|
|
103
103
|
if !@dependencies.nil?
|