inspec-core 2.1.67
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 +7 -0
- data/CHANGELOG.md +3136 -0
- data/Gemfile +56 -0
- data/LICENSE +14 -0
- data/MAINTAINERS.md +33 -0
- data/MAINTAINERS.toml +52 -0
- data/README.md +453 -0
- data/bin/inspec +12 -0
- data/docs/.gitignore +2 -0
- data/docs/README.md +40 -0
- data/docs/dev/control-eval.md +62 -0
- data/docs/dsl_inspec.md +258 -0
- data/docs/dsl_resource.md +100 -0
- data/docs/glossary.md +99 -0
- data/docs/habitat.md +192 -0
- data/docs/inspec_and_friends.md +114 -0
- data/docs/matchers.md +169 -0
- data/docs/migration.md +293 -0
- data/docs/platforms.md +119 -0
- data/docs/plugin_kitchen_inspec.md +50 -0
- data/docs/profiles.md +378 -0
- data/docs/reporters.md +105 -0
- data/docs/resources/aide_conf.md.erb +76 -0
- data/docs/resources/apache.md.erb +67 -0
- data/docs/resources/apache_conf.md.erb +68 -0
- data/docs/resources/apt.md.erb +71 -0
- data/docs/resources/audit_policy.md.erb +47 -0
- data/docs/resources/auditd.md.erb +79 -0
- data/docs/resources/auditd_conf.md.erb +68 -0
- data/docs/resources/bash.md.erb +75 -0
- data/docs/resources/bond.md.erb +90 -0
- data/docs/resources/bridge.md.erb +57 -0
- data/docs/resources/bsd_service.md.erb +67 -0
- data/docs/resources/chocolatey_package.md.erb +58 -0
- data/docs/resources/command.md.erb +138 -0
- data/docs/resources/cpan.md.erb +79 -0
- data/docs/resources/cran.md.erb +64 -0
- data/docs/resources/crontab.md.erb +89 -0
- data/docs/resources/csv.md.erb +54 -0
- data/docs/resources/dh_params.md.erb +205 -0
- data/docs/resources/directory.md.erb +30 -0
- data/docs/resources/docker.md.erb +219 -0
- data/docs/resources/docker_container.md.erb +103 -0
- data/docs/resources/docker_image.md.erb +94 -0
- data/docs/resources/docker_service.md.erb +114 -0
- data/docs/resources/elasticsearch.md.erb +242 -0
- data/docs/resources/etc_fstab.md.erb +125 -0
- data/docs/resources/etc_group.md.erb +75 -0
- data/docs/resources/etc_hosts.md.erb +78 -0
- data/docs/resources/etc_hosts_allow.md.erb +74 -0
- data/docs/resources/etc_hosts_deny.md.erb +74 -0
- data/docs/resources/file.md.erb +526 -0
- data/docs/resources/filesystem.md.erb +41 -0
- data/docs/resources/firewalld.md.erb +107 -0
- data/docs/resources/gem.md.erb +79 -0
- data/docs/resources/group.md.erb +61 -0
- data/docs/resources/grub_conf.md.erb +101 -0
- data/docs/resources/host.md.erb +86 -0
- data/docs/resources/http.md.erb +197 -0
- data/docs/resources/iis_app.md.erb +122 -0
- data/docs/resources/iis_site.md.erb +135 -0
- data/docs/resources/inetd_conf.md.erb +94 -0
- data/docs/resources/ini.md.erb +76 -0
- data/docs/resources/interface.md.erb +58 -0
- data/docs/resources/iptables.md.erb +64 -0
- data/docs/resources/json.md.erb +63 -0
- data/docs/resources/kernel_module.md.erb +120 -0
- data/docs/resources/kernel_parameter.md.erb +53 -0
- data/docs/resources/key_rsa.md.erb +85 -0
- data/docs/resources/launchd_service.md.erb +57 -0
- data/docs/resources/limits_conf.md.erb +75 -0
- data/docs/resources/login_defs.md.erb +71 -0
- data/docs/resources/mount.md.erb +69 -0
- data/docs/resources/mssql_session.md.erb +60 -0
- data/docs/resources/mysql_conf.md.erb +99 -0
- data/docs/resources/mysql_session.md.erb +74 -0
- data/docs/resources/nginx.md.erb +79 -0
- data/docs/resources/nginx_conf.md.erb +138 -0
- data/docs/resources/npm.md.erb +60 -0
- data/docs/resources/ntp_conf.md.erb +60 -0
- data/docs/resources/oneget.md.erb +53 -0
- data/docs/resources/oracledb_session.md.erb +52 -0
- data/docs/resources/os.md.erb +141 -0
- data/docs/resources/os_env.md.erb +91 -0
- data/docs/resources/package.md.erb +120 -0
- data/docs/resources/packages.md.erb +67 -0
- data/docs/resources/parse_config.md.erb +103 -0
- data/docs/resources/parse_config_file.md.erb +138 -0
- data/docs/resources/passwd.md.erb +141 -0
- data/docs/resources/pip.md.erb +67 -0
- data/docs/resources/port.md.erb +137 -0
- data/docs/resources/postgres_conf.md.erb +79 -0
- data/docs/resources/postgres_hba_conf.md.erb +93 -0
- data/docs/resources/postgres_ident_conf.md.erb +76 -0
- data/docs/resources/postgres_session.md.erb +69 -0
- data/docs/resources/powershell.md.erb +102 -0
- data/docs/resources/processes.md.erb +109 -0
- data/docs/resources/rabbitmq_config.md.erb +41 -0
- data/docs/resources/registry_key.md.erb +158 -0
- data/docs/resources/runit_service.md.erb +57 -0
- data/docs/resources/security_policy.md.erb +47 -0
- data/docs/resources/service.md.erb +121 -0
- data/docs/resources/shadow.md.erb +146 -0
- data/docs/resources/ssh_config.md.erb +73 -0
- data/docs/resources/sshd_config.md.erb +83 -0
- data/docs/resources/ssl.md.erb +119 -0
- data/docs/resources/sys_info.md.erb +42 -0
- data/docs/resources/systemd_service.md.erb +57 -0
- data/docs/resources/sysv_service.md.erb +57 -0
- data/docs/resources/upstart_service.md.erb +57 -0
- data/docs/resources/user.md.erb +140 -0
- data/docs/resources/users.md.erb +127 -0
- data/docs/resources/vbscript.md.erb +55 -0
- data/docs/resources/virtualization.md.erb +57 -0
- data/docs/resources/windows_feature.md.erb +47 -0
- data/docs/resources/windows_hotfix.md.erb +53 -0
- data/docs/resources/windows_task.md.erb +95 -0
- data/docs/resources/wmi.md.erb +81 -0
- data/docs/resources/x509_certificate.md.erb +151 -0
- data/docs/resources/xinetd_conf.md.erb +156 -0
- data/docs/resources/xml.md.erb +85 -0
- data/docs/resources/yaml.md.erb +69 -0
- data/docs/resources/yum.md.erb +98 -0
- data/docs/resources/zfs_dataset.md.erb +53 -0
- data/docs/resources/zfs_pool.md.erb +47 -0
- data/docs/ruby_usage.md +203 -0
- data/docs/shared/matcher_be.md.erb +1 -0
- data/docs/shared/matcher_cmp.md.erb +43 -0
- data/docs/shared/matcher_eq.md.erb +3 -0
- data/docs/shared/matcher_include.md.erb +1 -0
- data/docs/shared/matcher_match.md.erb +1 -0
- data/docs/shell.md +217 -0
- data/examples/README.md +8 -0
- data/examples/inheritance/README.md +65 -0
- data/examples/inheritance/controls/example.rb +14 -0
- data/examples/inheritance/inspec.yml +15 -0
- data/examples/kitchen-ansible/.kitchen.yml +25 -0
- data/examples/kitchen-ansible/Gemfile +19 -0
- data/examples/kitchen-ansible/README.md +53 -0
- data/examples/kitchen-ansible/files/nginx.repo +6 -0
- data/examples/kitchen-ansible/tasks/main.yml +16 -0
- data/examples/kitchen-ansible/test/integration/default/default.yml +5 -0
- data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-chef/.kitchen.yml +20 -0
- data/examples/kitchen-chef/Berksfile +3 -0
- data/examples/kitchen-chef/Gemfile +19 -0
- data/examples/kitchen-chef/README.md +27 -0
- data/examples/kitchen-chef/metadata.rb +7 -0
- data/examples/kitchen-chef/recipes/default.rb +6 -0
- data/examples/kitchen-chef/recipes/nginx.rb +30 -0
- data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-puppet/.kitchen.yml +23 -0
- data/examples/kitchen-puppet/Gemfile +20 -0
- data/examples/kitchen-puppet/Puppetfile +25 -0
- data/examples/kitchen-puppet/README.md +53 -0
- data/examples/kitchen-puppet/manifests/site.pp +33 -0
- data/examples/kitchen-puppet/metadata.json +11 -0
- data/examples/kitchen-puppet/modules/.gitkeep +0 -0
- data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -0
- data/examples/meta-profile/README.md +37 -0
- data/examples/meta-profile/controls/example.rb +13 -0
- data/examples/meta-profile/inspec.yml +13 -0
- data/examples/profile-attribute.yml +2 -0
- data/examples/profile-attribute/README.md +14 -0
- data/examples/profile-attribute/controls/example.rb +11 -0
- data/examples/profile-attribute/inspec.yml +8 -0
- 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/examples/profile/README.md +48 -0
- data/examples/profile/controls/example.rb +23 -0
- data/examples/profile/controls/gordon.rb +36 -0
- data/examples/profile/controls/meta.rb +34 -0
- data/examples/profile/inspec.yml +10 -0
- data/examples/profile/libraries/gordon_config.rb +59 -0
- data/inspec-core.gemspec +43 -0
- data/lib/bundles/README.md +3 -0
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +277 -0
- data/lib/bundles/inspec-compliance.rb +16 -0
- data/lib/bundles/inspec-compliance/.kitchen.yml +20 -0
- data/lib/bundles/inspec-compliance/README.md +193 -0
- data/lib/bundles/inspec-compliance/api.rb +360 -0
- data/lib/bundles/inspec-compliance/api/login.rb +193 -0
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -0
- data/lib/bundles/inspec-compliance/cli.rb +260 -0
- data/lib/bundles/inspec-compliance/configuration.rb +103 -0
- data/lib/bundles/inspec-compliance/http.rb +125 -0
- data/lib/bundles/inspec-compliance/images/cc-token.png +0 -0
- data/lib/bundles/inspec-compliance/support.rb +36 -0
- data/lib/bundles/inspec-compliance/target.rb +106 -0
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -0
- data/lib/bundles/inspec-habitat.rb +12 -0
- data/lib/bundles/inspec-habitat/cli.rb +36 -0
- data/lib/bundles/inspec-habitat/log.rb +10 -0
- data/lib/bundles/inspec-habitat/profile.rb +391 -0
- data/lib/bundles/inspec-init.rb +8 -0
- data/lib/bundles/inspec-init/README.md +31 -0
- data/lib/bundles/inspec-init/cli.rb +97 -0
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -0
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -0
- data/lib/bundles/inspec-init/templates/profile/libraries/.gitkeep +0 -0
- data/lib/bundles/inspec-supermarket.rb +13 -0
- data/lib/bundles/inspec-supermarket/README.md +45 -0
- data/lib/bundles/inspec-supermarket/api.rb +84 -0
- data/lib/bundles/inspec-supermarket/cli.rb +73 -0
- data/lib/bundles/inspec-supermarket/target.rb +34 -0
- data/lib/fetchers/git.rb +163 -0
- data/lib/fetchers/local.rb +74 -0
- data/lib/fetchers/mock.rb +35 -0
- data/lib/fetchers/url.rb +247 -0
- data/lib/inspec.rb +24 -0
- data/lib/inspec/archive/tar.rb +29 -0
- data/lib/inspec/archive/zip.rb +19 -0
- data/lib/inspec/backend.rb +93 -0
- data/lib/inspec/base_cli.rb +368 -0
- data/lib/inspec/cached_fetcher.rb +66 -0
- data/lib/inspec/cli.rb +292 -0
- data/lib/inspec/completions/bash.sh.erb +45 -0
- data/lib/inspec/completions/fish.sh.erb +34 -0
- data/lib/inspec/completions/zsh.sh.erb +61 -0
- data/lib/inspec/control_eval_context.rb +179 -0
- data/lib/inspec/dependencies/cache.rb +72 -0
- data/lib/inspec/dependencies/dependency_set.rb +92 -0
- data/lib/inspec/dependencies/lockfile.rb +115 -0
- data/lib/inspec/dependencies/requirement.rb +123 -0
- data/lib/inspec/dependencies/resolver.rb +86 -0
- data/lib/inspec/describe.rb +27 -0
- data/lib/inspec/dsl.rb +66 -0
- data/lib/inspec/dsl_shared.rb +33 -0
- data/lib/inspec/env_printer.rb +157 -0
- data/lib/inspec/errors.rb +14 -0
- data/lib/inspec/exceptions.rb +12 -0
- data/lib/inspec/expect.rb +45 -0
- data/lib/inspec/fetcher.rb +45 -0
- data/lib/inspec/file_provider.rb +275 -0
- data/lib/inspec/formatters.rb +3 -0
- data/lib/inspec/formatters/base.rb +259 -0
- data/lib/inspec/formatters/json_rspec.rb +20 -0
- data/lib/inspec/formatters/show_progress.rb +12 -0
- data/lib/inspec/library_eval_context.rb +58 -0
- data/lib/inspec/log.rb +11 -0
- data/lib/inspec/metadata.rb +247 -0
- data/lib/inspec/method_source.rb +24 -0
- data/lib/inspec/objects.rb +14 -0
- data/lib/inspec/objects/attribute.rb +75 -0
- data/lib/inspec/objects/control.rb +61 -0
- data/lib/inspec/objects/describe.rb +92 -0
- data/lib/inspec/objects/each_loop.rb +36 -0
- data/lib/inspec/objects/list.rb +15 -0
- data/lib/inspec/objects/or_test.rb +40 -0
- data/lib/inspec/objects/ruby_helper.rb +15 -0
- data/lib/inspec/objects/tag.rb +27 -0
- data/lib/inspec/objects/test.rb +87 -0
- data/lib/inspec/objects/value.rb +27 -0
- data/lib/inspec/plugins.rb +60 -0
- data/lib/inspec/plugins/cli.rb +24 -0
- data/lib/inspec/plugins/fetcher.rb +86 -0
- data/lib/inspec/plugins/resource.rb +135 -0
- data/lib/inspec/plugins/secret.rb +15 -0
- data/lib/inspec/plugins/source_reader.rb +40 -0
- data/lib/inspec/polyfill.rb +12 -0
- data/lib/inspec/profile.rb +513 -0
- data/lib/inspec/profile_context.rb +208 -0
- data/lib/inspec/profile_vendor.rb +66 -0
- data/lib/inspec/reporters.rb +60 -0
- data/lib/inspec/reporters/automate.rb +76 -0
- data/lib/inspec/reporters/base.rb +25 -0
- data/lib/inspec/reporters/cli.rb +356 -0
- data/lib/inspec/reporters/json.rb +116 -0
- data/lib/inspec/reporters/json_min.rb +48 -0
- data/lib/inspec/reporters/junit.rb +78 -0
- data/lib/inspec/require_loader.rb +33 -0
- data/lib/inspec/resource.rb +190 -0
- data/lib/inspec/rule.rb +280 -0
- data/lib/inspec/runner.rb +345 -0
- data/lib/inspec/runner_mock.rb +41 -0
- data/lib/inspec/runner_rspec.rb +175 -0
- data/lib/inspec/runtime_profile.rb +26 -0
- data/lib/inspec/schema.rb +213 -0
- data/lib/inspec/secrets.rb +19 -0
- data/lib/inspec/secrets/yaml.rb +30 -0
- data/lib/inspec/shell.rb +220 -0
- data/lib/inspec/shell_detector.rb +90 -0
- data/lib/inspec/source_reader.rb +29 -0
- data/lib/inspec/version.rb +8 -0
- data/lib/matchers/matchers.rb +339 -0
- data/lib/resources/aide_conf.rb +151 -0
- data/lib/resources/apache.rb +48 -0
- data/lib/resources/apache_conf.rb +149 -0
- data/lib/resources/apt.rb +149 -0
- data/lib/resources/audit_policy.rb +63 -0
- data/lib/resources/auditd.rb +231 -0
- data/lib/resources/auditd_conf.rb +46 -0
- data/lib/resources/bash.rb +35 -0
- data/lib/resources/bond.rb +69 -0
- data/lib/resources/bridge.rb +122 -0
- data/lib/resources/chocolatey_package.rb +78 -0
- data/lib/resources/command.rb +73 -0
- data/lib/resources/cpan.rb +58 -0
- data/lib/resources/cran.rb +64 -0
- data/lib/resources/crontab.rb +169 -0
- data/lib/resources/csv.rb +56 -0
- data/lib/resources/dh_params.rb +77 -0
- data/lib/resources/directory.rb +25 -0
- data/lib/resources/docker.rb +236 -0
- data/lib/resources/docker_container.rb +89 -0
- data/lib/resources/docker_image.rb +83 -0
- data/lib/resources/docker_object.rb +57 -0
- data/lib/resources/docker_service.rb +90 -0
- data/lib/resources/elasticsearch.rb +169 -0
- data/lib/resources/etc_fstab.rb +94 -0
- data/lib/resources/etc_group.rb +154 -0
- data/lib/resources/etc_hosts.rb +66 -0
- data/lib/resources/etc_hosts_allow_deny.rb +112 -0
- data/lib/resources/file.rb +298 -0
- data/lib/resources/filesystem.rb +31 -0
- data/lib/resources/firewalld.rb +143 -0
- data/lib/resources/gem.rb +70 -0
- data/lib/resources/groups.rb +215 -0
- data/lib/resources/grub_conf.rb +227 -0
- data/lib/resources/host.rb +306 -0
- data/lib/resources/http.rb +253 -0
- data/lib/resources/iis_app.rb +101 -0
- data/lib/resources/iis_site.rb +148 -0
- data/lib/resources/inetd_conf.rb +54 -0
- data/lib/resources/ini.rb +29 -0
- data/lib/resources/interface.rb +129 -0
- data/lib/resources/iptables.rb +80 -0
- data/lib/resources/json.rb +111 -0
- data/lib/resources/kernel_module.rb +107 -0
- data/lib/resources/kernel_parameter.rb +58 -0
- data/lib/resources/key_rsa.rb +63 -0
- data/lib/resources/limits_conf.rb +46 -0
- data/lib/resources/login_def.rb +57 -0
- data/lib/resources/mount.rb +88 -0
- data/lib/resources/mssql_session.rb +101 -0
- data/lib/resources/mysql.rb +82 -0
- data/lib/resources/mysql_conf.rb +127 -0
- data/lib/resources/mysql_session.rb +85 -0
- data/lib/resources/nginx.rb +96 -0
- data/lib/resources/nginx_conf.rb +226 -0
- data/lib/resources/npm.rb +48 -0
- data/lib/resources/ntp_conf.rb +51 -0
- data/lib/resources/oneget.rb +71 -0
- data/lib/resources/oracledb_session.rb +139 -0
- data/lib/resources/os.rb +36 -0
- data/lib/resources/os_env.rb +86 -0
- data/lib/resources/package.rb +370 -0
- data/lib/resources/packages.rb +111 -0
- data/lib/resources/parse_config.rb +112 -0
- data/lib/resources/passwd.rb +76 -0
- data/lib/resources/pip.rb +130 -0
- data/lib/resources/platform.rb +109 -0
- data/lib/resources/port.rb +771 -0
- data/lib/resources/postgres.rb +131 -0
- data/lib/resources/postgres_conf.rb +114 -0
- data/lib/resources/postgres_hba_conf.rb +90 -0
- data/lib/resources/postgres_ident_conf.rb +79 -0
- data/lib/resources/postgres_session.rb +71 -0
- data/lib/resources/powershell.rb +67 -0
- data/lib/resources/processes.rb +204 -0
- data/lib/resources/rabbitmq_conf.rb +51 -0
- data/lib/resources/registry_key.rb +297 -0
- data/lib/resources/security_policy.rb +180 -0
- data/lib/resources/service.rb +794 -0
- data/lib/resources/shadow.rb +159 -0
- data/lib/resources/ssh_conf.rb +97 -0
- data/lib/resources/ssl.rb +99 -0
- data/lib/resources/sys_info.rb +28 -0
- data/lib/resources/toml.rb +32 -0
- data/lib/resources/users.rb +654 -0
- data/lib/resources/vbscript.rb +68 -0
- data/lib/resources/virtualization.rb +247 -0
- data/lib/resources/windows_feature.rb +84 -0
- data/lib/resources/windows_hotfix.rb +35 -0
- data/lib/resources/windows_task.rb +102 -0
- data/lib/resources/wmi.rb +110 -0
- data/lib/resources/x509_certificate.rb +137 -0
- data/lib/resources/xinetd.rb +106 -0
- data/lib/resources/xml.rb +46 -0
- data/lib/resources/yaml.rb +43 -0
- data/lib/resources/yum.rb +180 -0
- data/lib/resources/zfs_dataset.rb +60 -0
- data/lib/resources/zfs_pool.rb +49 -0
- data/lib/source_readers/flat.rb +39 -0
- data/lib/source_readers/inspec.rb +75 -0
- data/lib/utils/command_wrapper.rb +27 -0
- data/lib/utils/convert.rb +12 -0
- data/lib/utils/database_helpers.rb +77 -0
- data/lib/utils/enumerable_delegation.rb +9 -0
- data/lib/utils/erlang_parser.rb +192 -0
- data/lib/utils/file_reader.rb +25 -0
- data/lib/utils/filter.rb +273 -0
- data/lib/utils/filter_array.rb +27 -0
- data/lib/utils/find_files.rb +47 -0
- data/lib/utils/hash.rb +41 -0
- data/lib/utils/json_log.rb +18 -0
- data/lib/utils/latest_version.rb +22 -0
- data/lib/utils/modulator.rb +12 -0
- data/lib/utils/nginx_parser.rb +105 -0
- data/lib/utils/object_traversal.rb +49 -0
- data/lib/utils/parser.rb +274 -0
- data/lib/utils/pkey_reader.rb +15 -0
- data/lib/utils/plugin_registry.rb +93 -0
- data/lib/utils/simpleconfig.rb +120 -0
- data/lib/utils/spdx.rb +13 -0
- data/lib/utils/spdx.txt +344 -0
- metadata +713 -0
@@ -0,0 +1,368 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
require 'thor'
|
6
|
+
require 'inspec/log'
|
7
|
+
require 'inspec/profile_vendor'
|
8
|
+
|
9
|
+
module Inspec
|
10
|
+
class BaseCLI < Thor
|
11
|
+
# https://github.com/erikhuda/thor/issues/244
|
12
|
+
def self.exit_on_failure?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.target_options
|
17
|
+
option :target, aliases: :t, type: :string,
|
18
|
+
desc: 'Simple targeting option using URIs, e.g. ssh://user:pass@host:port'
|
19
|
+
option :backend, aliases: :b, type: :string,
|
20
|
+
desc: 'Choose a backend: local, ssh, winrm, docker.'
|
21
|
+
option :host, type: :string,
|
22
|
+
desc: 'Specify a remote host which is tested.'
|
23
|
+
option :port, aliases: :p, type: :numeric,
|
24
|
+
desc: 'Specify the login port for a remote scan.'
|
25
|
+
option :user, type: :string,
|
26
|
+
desc: 'The login user for a remote scan.'
|
27
|
+
option :password, type: :string, lazy_default: -1,
|
28
|
+
desc: 'Login password for a remote scan, if required.'
|
29
|
+
option :enable_password, type: :string, lazy_default: -1,
|
30
|
+
desc: 'Password for enable mode on Cisco IOS devices.'
|
31
|
+
option :key_files, aliases: :i, type: :array,
|
32
|
+
desc: 'Login key or certificate file for a remote scan.'
|
33
|
+
option :path, type: :string,
|
34
|
+
desc: 'Login path to use when connecting to the target (WinRM).'
|
35
|
+
option :sudo, type: :boolean,
|
36
|
+
desc: 'Run scans with sudo. Only activates on Unix and non-root user.'
|
37
|
+
option :sudo_password, type: :string, lazy_default: -1,
|
38
|
+
desc: 'Specify a sudo password, if it is required.'
|
39
|
+
option :sudo_options, type: :string,
|
40
|
+
desc: 'Additional sudo options for a remote scan.'
|
41
|
+
option :sudo_command, type: :string,
|
42
|
+
desc: 'Alternate command for sudo.'
|
43
|
+
option :shell, type: :boolean,
|
44
|
+
desc: 'Run scans in a subshell. Only activates on Unix.'
|
45
|
+
option :shell_options, type: :string,
|
46
|
+
desc: 'Additional shell options.'
|
47
|
+
option :shell_command, type: :string,
|
48
|
+
desc: 'Specify a particular shell to use.'
|
49
|
+
option :ssl, type: :boolean,
|
50
|
+
desc: 'Use SSL for transport layer encryption (WinRM).'
|
51
|
+
option :self_signed, type: :boolean,
|
52
|
+
desc: 'Allow remote scans with self-signed certificates (WinRM).'
|
53
|
+
option :json_config, type: :string,
|
54
|
+
desc: 'Read configuration from JSON file (`-` reads from stdin).'
|
55
|
+
option :proxy_command, type: :string,
|
56
|
+
desc: 'Specifies the command to use to connect to the server'
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.profile_options
|
60
|
+
option :profiles_path, type: :string,
|
61
|
+
desc: 'Folder which contains referenced profiles.'
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.exec_options
|
65
|
+
target_options
|
66
|
+
profile_options
|
67
|
+
option :controls, type: :array,
|
68
|
+
desc: 'A list of controls to run. Ignore all other tests.'
|
69
|
+
option :format, type: :string,
|
70
|
+
desc: '[DEPRECATED] Please use --reporter - this will be removed in InSpec 3.0'
|
71
|
+
option :reporter, type: :array,
|
72
|
+
banner: 'one two:/output/file/path',
|
73
|
+
desc: 'Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit'
|
74
|
+
option :color, type: :boolean,
|
75
|
+
desc: 'Use colors in output.'
|
76
|
+
option :attrs, type: :array,
|
77
|
+
desc: 'Load attributes file (experimental)'
|
78
|
+
option :vendor_cache, type: :string,
|
79
|
+
desc: 'Use the given path for caching dependencies. (default: ~/.inspec/cache)'
|
80
|
+
option :create_lockfile, type: :boolean,
|
81
|
+
desc: 'Write out a lockfile based on this execution (unless one already exists)'
|
82
|
+
option :backend_cache, type: :boolean,
|
83
|
+
desc: 'Allow caching for backend command output. (default: true)'
|
84
|
+
option :show_progress, type: :boolean,
|
85
|
+
desc: 'Show progress while executing tests.'
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.default_options
|
89
|
+
{
|
90
|
+
exec: {
|
91
|
+
'reporter' => ['cli'],
|
92
|
+
'show_progress' => false,
|
93
|
+
'color' => true,
|
94
|
+
'create_lockfile' => true,
|
95
|
+
'backend_cache' => true,
|
96
|
+
},
|
97
|
+
shell: {
|
98
|
+
'reporter' => ['cli'],
|
99
|
+
},
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.parse_reporters(opts) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
104
|
+
# merge in any legacy formats as reporter
|
105
|
+
# this method will only be used for ad-hoc runners
|
106
|
+
if !opts['format'].nil? && opts['reporter'].nil?
|
107
|
+
warn '[DEPRECATED] The option --format is being deprecated and will be removed in inspec 3.0. Please use --reporter'
|
108
|
+
|
109
|
+
# see if we are using the legacy output to write to files
|
110
|
+
if opts['output']
|
111
|
+
warn '[DEPRECATED] The option \'output\' is being deprecated and will be removed in inspec 3.0. Please use --reporter name:path'
|
112
|
+
opts['format'] = "#{opts['format']}:#{opts['output']}"
|
113
|
+
opts.delete('output')
|
114
|
+
end
|
115
|
+
|
116
|
+
opts['reporter'] = Array(opts['format'])
|
117
|
+
opts.delete('format')
|
118
|
+
end
|
119
|
+
|
120
|
+
# default to cli report for ad-hoc runners
|
121
|
+
opts['reporter'] = ['cli'] if opts['reporter'].nil?
|
122
|
+
|
123
|
+
# parse out cli to proper report format
|
124
|
+
if opts['reporter'].is_a?(Array)
|
125
|
+
reports = {}
|
126
|
+
opts['reporter'].each do |report|
|
127
|
+
reporter_name, target = report.split(':')
|
128
|
+
if target.nil? || target.strip == '-'
|
129
|
+
reports[reporter_name] = { 'stdout' => true }
|
130
|
+
else
|
131
|
+
reports[reporter_name] = {
|
132
|
+
'file' => target,
|
133
|
+
'stdout' => false,
|
134
|
+
}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
opts['reporter'] = reports
|
138
|
+
end
|
139
|
+
|
140
|
+
# add in stdout if not specified
|
141
|
+
if opts['reporter'].is_a?(Hash)
|
142
|
+
opts['reporter'].each do |reporter_name, config|
|
143
|
+
opts['reporter'][reporter_name] = {} if config.nil?
|
144
|
+
opts['reporter'][reporter_name]['stdout'] = true if opts['reporter'][reporter_name].empty?
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
validate_reporters(opts['reporter'])
|
149
|
+
opts
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.validate_reporters(reporters)
|
153
|
+
return if reporters.nil?
|
154
|
+
|
155
|
+
valid_types = [
|
156
|
+
'automate',
|
157
|
+
'cli',
|
158
|
+
'documentation',
|
159
|
+
'html',
|
160
|
+
'json',
|
161
|
+
'json-min',
|
162
|
+
'json-rspec',
|
163
|
+
'junit',
|
164
|
+
'progress',
|
165
|
+
]
|
166
|
+
|
167
|
+
reporters.each do |k, v|
|
168
|
+
raise NotImplementedError, "'#{k}' is not a valid reporter type." unless valid_types.include?(k)
|
169
|
+
|
170
|
+
next unless k == 'automate'
|
171
|
+
%w{token url}.each do |option|
|
172
|
+
raise Inspec::ReporterError, "You must specify a automate #{option} via the json-config." if v[option].nil?
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# check to make sure we are only reporting one type to stdout
|
177
|
+
stdout = 0
|
178
|
+
reporters.each_value do |v|
|
179
|
+
stdout += 1 if v['stdout'] == true
|
180
|
+
end
|
181
|
+
|
182
|
+
raise ArgumentError, 'The option --reporter can only have a single report outputting to stdout.' if stdout > 1
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.detect(params: {}, indent: 0, color: 39)
|
186
|
+
str = ''
|
187
|
+
params.each { |item, info|
|
188
|
+
data = info
|
189
|
+
|
190
|
+
# Format Array for better output if applicable
|
191
|
+
data = data.join(', ') if data.is_a?(Array)
|
192
|
+
|
193
|
+
# Do not output fields of data is missing ('unknown' is fine)
|
194
|
+
next if data.nil?
|
195
|
+
|
196
|
+
data = "\e[1m\e[#{color}m#{data}\e[0m"
|
197
|
+
str << format("#{' ' * indent}%-10s %s\n", item.to_s.capitalize + ':', data)
|
198
|
+
}
|
199
|
+
str
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def suppress_log_output?(opts)
|
205
|
+
return false if opts['reporter'].nil?
|
206
|
+
match = %w{json json-min json-rspec junit html} & opts['reporter'].keys
|
207
|
+
unless match.empty?
|
208
|
+
match.each do |m|
|
209
|
+
# check to see if we are outputting to stdout
|
210
|
+
return true if opts['reporter'][m]['stdout'] == true
|
211
|
+
end
|
212
|
+
end
|
213
|
+
false
|
214
|
+
end
|
215
|
+
|
216
|
+
def diagnose(opts)
|
217
|
+
return unless opts['diagnose']
|
218
|
+
puts "InSpec version: #{Inspec::VERSION}"
|
219
|
+
puts "Train version: #{Train::VERSION}"
|
220
|
+
puts 'Command line configuration:'
|
221
|
+
pp options
|
222
|
+
puts 'JSON configuration file:'
|
223
|
+
pp options_json
|
224
|
+
puts 'Merged configuration:'
|
225
|
+
pp opts
|
226
|
+
puts
|
227
|
+
end
|
228
|
+
|
229
|
+
def opts(type = nil)
|
230
|
+
o = merged_opts(type)
|
231
|
+
|
232
|
+
# Due to limitations in Thor it is not possible to set an argument to be
|
233
|
+
# both optional and its value to be mandatory. E.g. the user supplying
|
234
|
+
# the --password argument is optional and not always required, but
|
235
|
+
# whenever it is used, it requires a value. Handle options that were
|
236
|
+
# defined above and require a value here:
|
237
|
+
%w{password sudo-password}.each do |v|
|
238
|
+
id = v.tr('-', '_').to_sym
|
239
|
+
next unless o[id] == -1
|
240
|
+
raise ArgumentError, "Please provide a value for --#{v}. For example: --#{v}=hello."
|
241
|
+
end
|
242
|
+
|
243
|
+
# check for compliance settings
|
244
|
+
Compliance::API.login(o['compliance']) if o['compliance']
|
245
|
+
|
246
|
+
o
|
247
|
+
end
|
248
|
+
|
249
|
+
def merged_opts(type = nil)
|
250
|
+
opts = {}
|
251
|
+
|
252
|
+
# start with default options if we have any
|
253
|
+
opts = BaseCLI.default_options[type] unless type.nil? || BaseCLI.default_options[type].nil?
|
254
|
+
opts['type'] = type unless type.nil?
|
255
|
+
|
256
|
+
# merge in any options from json-config
|
257
|
+
json_config = options_json
|
258
|
+
opts.merge!(json_config)
|
259
|
+
|
260
|
+
# remove the default reporter if we are setting a legacy format on the cli
|
261
|
+
# or via json-config
|
262
|
+
opts.delete('reporter') if options['format'] || json_config['format']
|
263
|
+
|
264
|
+
# merge in any options defined via thor
|
265
|
+
opts.merge!(options)
|
266
|
+
|
267
|
+
# parse reporter options
|
268
|
+
opts = BaseCLI.parse_reporters(opts) if %i(exec shell).include?(type)
|
269
|
+
|
270
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(opts)
|
271
|
+
end
|
272
|
+
|
273
|
+
def options_json
|
274
|
+
conffile = options['json_config']
|
275
|
+
@json ||= conffile ? read_config(conffile) : {}
|
276
|
+
end
|
277
|
+
|
278
|
+
def read_config(file)
|
279
|
+
if file == '-'
|
280
|
+
puts 'WARN: reading JSON config from standard input' if STDIN.tty?
|
281
|
+
config = STDIN.read
|
282
|
+
else
|
283
|
+
config = File.read(file)
|
284
|
+
end
|
285
|
+
|
286
|
+
JSON.parse(config)
|
287
|
+
rescue JSON::ParserError => e
|
288
|
+
puts "Failed to load JSON configuration: #{e}\nConfig was: #{config.inspect}"
|
289
|
+
exit 1
|
290
|
+
end
|
291
|
+
|
292
|
+
# get the log level
|
293
|
+
# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
294
|
+
def get_log_level(level)
|
295
|
+
valid = %w{debug info warn error fatal}
|
296
|
+
|
297
|
+
if valid.include?(level)
|
298
|
+
l = level
|
299
|
+
else
|
300
|
+
l = 'info'
|
301
|
+
end
|
302
|
+
|
303
|
+
Logger.const_get(l.upcase)
|
304
|
+
end
|
305
|
+
|
306
|
+
def pretty_handle_exception(exception)
|
307
|
+
case exception
|
308
|
+
when Inspec::Error
|
309
|
+
$stderr.puts exception.message
|
310
|
+
exit(1)
|
311
|
+
else
|
312
|
+
raise exception
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def vendor_deps(path, opts)
|
317
|
+
profile_path = path || Dir.pwd
|
318
|
+
profile_vendor = Inspec::ProfileVendor.new(profile_path)
|
319
|
+
|
320
|
+
if (profile_vendor.cache_path.exist? || profile_vendor.lockfile.exist?) && !opts[:overwrite]
|
321
|
+
puts 'Profile is already vendored. Use --overwrite.'
|
322
|
+
return false
|
323
|
+
end
|
324
|
+
|
325
|
+
profile_vendor.vendor!
|
326
|
+
puts "Dependencies for profile #{profile_path} successfully vendored to #{profile_vendor.cache_path}"
|
327
|
+
rescue StandardError => e
|
328
|
+
pretty_handle_exception(e)
|
329
|
+
end
|
330
|
+
|
331
|
+
def configure_logger(o)
|
332
|
+
#
|
333
|
+
# TODO(ssd): This is a big gross, but this configures the
|
334
|
+
# logging singleton Inspec::Log. Eventually it would be nice to
|
335
|
+
# move internal debug logging to use this logging singleton.
|
336
|
+
#
|
337
|
+
loc = if o.log_location
|
338
|
+
o.log_location
|
339
|
+
elsif suppress_log_output?(o)
|
340
|
+
STDERR
|
341
|
+
else
|
342
|
+
STDOUT
|
343
|
+
end
|
344
|
+
|
345
|
+
Inspec::Log.init(loc)
|
346
|
+
Inspec::Log.level = get_log_level(o.log_level)
|
347
|
+
|
348
|
+
o[:logger] = Logger.new(loc)
|
349
|
+
# output json if we have activated the json formatter
|
350
|
+
if o['log-format'] == 'json'
|
351
|
+
o[:logger].formatter = Logger::JSONFormatter.new
|
352
|
+
end
|
353
|
+
o[:logger].level = get_log_level(o.log_level)
|
354
|
+
end
|
355
|
+
|
356
|
+
def mark_text(text)
|
357
|
+
"\e[0;36m#{text}\e[0m"
|
358
|
+
end
|
359
|
+
|
360
|
+
def headline(title)
|
361
|
+
puts "\n== #{title}\n\n"
|
362
|
+
end
|
363
|
+
|
364
|
+
def li(entry)
|
365
|
+
puts " #{mark_text('*')} #{entry}"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'inspec/fetcher'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
class CachedFetcher
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
attr_reader :cache, :target, :fetcher
|
10
|
+
def initialize(target, cache)
|
11
|
+
@target = target
|
12
|
+
@fetcher = Inspec::Fetcher.resolve(target)
|
13
|
+
|
14
|
+
if @fetcher.nil?
|
15
|
+
raise("Could not fetch inspec profile in #{target.inspect}.")
|
16
|
+
end
|
17
|
+
|
18
|
+
@cache = cache
|
19
|
+
end
|
20
|
+
|
21
|
+
def resolved_source
|
22
|
+
fetch
|
23
|
+
@fetcher.resolved_source
|
24
|
+
end
|
25
|
+
|
26
|
+
def cache_key
|
27
|
+
k = if target.is_a?(Hash)
|
28
|
+
target[:sha256] || target[:ref]
|
29
|
+
end
|
30
|
+
|
31
|
+
if k.nil?
|
32
|
+
fetcher.cache_key
|
33
|
+
else
|
34
|
+
k
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch
|
39
|
+
if cache.exists?(cache_key)
|
40
|
+
Inspec::Log.debug "Using cached dependency for #{target}"
|
41
|
+
[cache.prefered_entry_for(cache_key), false]
|
42
|
+
else
|
43
|
+
Inspec::Log.debug "Dependency does not exist in the cache #{target}"
|
44
|
+
fetcher.fetch(cache.base_path_for(fetcher.cache_key))
|
45
|
+
assert_cache_sanity!
|
46
|
+
[fetcher.archive_path, fetcher.writable?]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def assert_cache_sanity!
|
51
|
+
return unless target.respond_to?(:key?) && target.key?(:sha256)
|
52
|
+
|
53
|
+
exception_message = <<~EOF
|
54
|
+
The remote source #{fetcher} no longer has the requested content:
|
55
|
+
|
56
|
+
Request Content Hash: #{target[:sha256]}
|
57
|
+
Actual Content Hash: #{fetcher.resolved_source[:sha256]}
|
58
|
+
|
59
|
+
For URL, supermarket, compliance, and other sources that do not
|
60
|
+
provide versioned artifacts, this likely means that the remote source
|
61
|
+
has changed since your lockfile was generated.
|
62
|
+
EOF
|
63
|
+
raise exception_message if fetcher.resolved_source[:sha256] != target[:sha256]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/inspec/cli.rb
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Copyright 2015 Dominik Richter
|
3
|
+
# author: Dominik Richter
|
4
|
+
# author: Christoph Hartmann
|
5
|
+
|
6
|
+
require 'logger'
|
7
|
+
require 'thor'
|
8
|
+
require 'json'
|
9
|
+
require 'pp'
|
10
|
+
require 'utils/json_log'
|
11
|
+
require 'utils/latest_version'
|
12
|
+
require 'inspec/base_cli'
|
13
|
+
require 'inspec/plugins'
|
14
|
+
require 'inspec/runner_mock'
|
15
|
+
require 'inspec/env_printer'
|
16
|
+
require 'inspec/schema'
|
17
|
+
|
18
|
+
class Inspec::InspecCLI < Inspec::BaseCLI
|
19
|
+
class_option :log_level, aliases: :l, type: :string,
|
20
|
+
desc: 'Set the log level: info (default), debug, warn, error'
|
21
|
+
|
22
|
+
class_option :log_location, type: :string,
|
23
|
+
desc: 'Location to send diagnostic log messages to. (default: STDOUT or STDERR)'
|
24
|
+
|
25
|
+
class_option :diagnose, type: :boolean,
|
26
|
+
desc: 'Show diagnostics (versions, configurations)'
|
27
|
+
|
28
|
+
desc 'json PATH', 'read all tests in PATH and generate a JSON summary'
|
29
|
+
option :output, aliases: :o, type: :string,
|
30
|
+
desc: 'Save the created profile to a path'
|
31
|
+
option :controls, type: :array,
|
32
|
+
desc: 'A list of controls to include. Ignore all other tests.'
|
33
|
+
profile_options
|
34
|
+
def json(target)
|
35
|
+
o = opts.dup
|
36
|
+
diagnose(o)
|
37
|
+
o[:ignore_supports] = true
|
38
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
39
|
+
o[:check_mode] = true
|
40
|
+
|
41
|
+
profile = Inspec::Profile.for_target(target, o)
|
42
|
+
info = profile.info
|
43
|
+
# add in inspec version
|
44
|
+
info[:generator] = {
|
45
|
+
name: 'inspec',
|
46
|
+
version: Inspec::VERSION,
|
47
|
+
}
|
48
|
+
dst = o[:output].to_s
|
49
|
+
if dst.empty?
|
50
|
+
puts JSON.dump(info)
|
51
|
+
else
|
52
|
+
if File.exist? dst
|
53
|
+
puts "----> updating #{dst}"
|
54
|
+
else
|
55
|
+
puts "----> creating #{dst}"
|
56
|
+
end
|
57
|
+
fdst = File.expand_path(dst)
|
58
|
+
File.write(fdst, JSON.dump(info))
|
59
|
+
end
|
60
|
+
rescue StandardError => e
|
61
|
+
pretty_handle_exception(e)
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'check PATH', 'verify all tests at the specified PATH'
|
65
|
+
option :format, type: :string
|
66
|
+
profile_options
|
67
|
+
def check(path) # rubocop:disable Metrics/AbcSize
|
68
|
+
o = opts.dup
|
69
|
+
diagnose(o)
|
70
|
+
o[:ignore_supports] = true # we check for integrity only
|
71
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
72
|
+
o[:check_mode] = true
|
73
|
+
|
74
|
+
# run check
|
75
|
+
profile = Inspec::Profile.for_target(path, o)
|
76
|
+
result = profile.check
|
77
|
+
|
78
|
+
if o['format'] == 'json'
|
79
|
+
puts JSON.generate(result)
|
80
|
+
else
|
81
|
+
%w{location profile controls timestamp valid}.each do |item|
|
82
|
+
puts format('%-12s %s', item.to_s.capitalize + ':',
|
83
|
+
mark_text(result[:summary][item.to_sym]))
|
84
|
+
end
|
85
|
+
puts
|
86
|
+
|
87
|
+
if result[:errors].empty? and result[:warnings].empty?
|
88
|
+
puts 'No errors or warnings'
|
89
|
+
else
|
90
|
+
red = "\033[31m"
|
91
|
+
yellow = "\033[33m"
|
92
|
+
rst = "\033[0m"
|
93
|
+
|
94
|
+
item_msg = lambda { |item|
|
95
|
+
pos = [item[:file], item[:line], item[:column]].compact.join(':')
|
96
|
+
pos.empty? ? item[:msg] : pos + ': ' + item[:msg]
|
97
|
+
}
|
98
|
+
result[:errors].each do |item|
|
99
|
+
puts "#{red} ✖ #{item_msg.call(item)}#{rst}"
|
100
|
+
end
|
101
|
+
result[:warnings].each do |item|
|
102
|
+
puts "#{yellow} ! #{item_msg.call(item)}#{rst}"
|
103
|
+
end
|
104
|
+
|
105
|
+
puts
|
106
|
+
puts format('Summary: %s%d errors%s, %s%d warnings%s',
|
107
|
+
red, result[:errors].length, rst,
|
108
|
+
yellow, result[:warnings].length, rst)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
exit 1 unless result[:summary][:valid]
|
112
|
+
rescue StandardError => e
|
113
|
+
pretty_handle_exception(e)
|
114
|
+
end
|
115
|
+
|
116
|
+
desc 'vendor PATH', 'Download all dependencies and generate a lockfile in a `vendor` directory'
|
117
|
+
option :overwrite, type: :boolean, default: false,
|
118
|
+
desc: 'Overwrite existing vendored dependencies and lockfile.'
|
119
|
+
def vendor(path = nil)
|
120
|
+
o = opts.dup
|
121
|
+
vendor_deps(path, o)
|
122
|
+
end
|
123
|
+
|
124
|
+
desc 'archive PATH', 'archive a profile to tar.gz (default) or zip'
|
125
|
+
profile_options
|
126
|
+
option :output, aliases: :o, type: :string,
|
127
|
+
desc: 'Save the archive to a path'
|
128
|
+
option :zip, type: :boolean, default: false,
|
129
|
+
desc: 'Generates a zip archive.'
|
130
|
+
option :tar, type: :boolean, default: false,
|
131
|
+
desc: 'Generates a tar.gz archive.'
|
132
|
+
option :overwrite, type: :boolean, default: false,
|
133
|
+
desc: 'Overwrite existing archive.'
|
134
|
+
option :ignore_errors, type: :boolean, default: false,
|
135
|
+
desc: 'Ignore profile warnings.'
|
136
|
+
def archive(path)
|
137
|
+
o = opts.dup
|
138
|
+
diagnose(o)
|
139
|
+
|
140
|
+
o[:logger] = Logger.new(STDOUT)
|
141
|
+
o[:logger].level = get_log_level(o.log_level)
|
142
|
+
o[:backend] = Inspec::Backend.create(target: 'mock://')
|
143
|
+
|
144
|
+
profile = Inspec::Profile.for_target(path, o)
|
145
|
+
result = profile.check
|
146
|
+
|
147
|
+
if result && !o[:ignore_errors] == false
|
148
|
+
o[:logger].info 'Profile check failed. Please fix the profile before generating an archive.'
|
149
|
+
return exit 1
|
150
|
+
end
|
151
|
+
|
152
|
+
# generate archive
|
153
|
+
exit 1 unless profile.archive(o)
|
154
|
+
rescue StandardError => e
|
155
|
+
pretty_handle_exception(e)
|
156
|
+
end
|
157
|
+
|
158
|
+
desc 'exec PATHS', 'run all test files at the specified PATH.'
|
159
|
+
exec_options
|
160
|
+
def exec(*targets)
|
161
|
+
o = opts(:exec).dup
|
162
|
+
diagnose(o)
|
163
|
+
configure_logger(o)
|
164
|
+
|
165
|
+
runner = Inspec::Runner.new(o)
|
166
|
+
targets.each { |target| runner.add_target(target) }
|
167
|
+
|
168
|
+
exit runner.run
|
169
|
+
rescue ArgumentError, RuntimeError, Train::UserError => e
|
170
|
+
$stderr.puts e.message
|
171
|
+
exit 1
|
172
|
+
rescue StandardError => e
|
173
|
+
pretty_handle_exception(e)
|
174
|
+
end
|
175
|
+
|
176
|
+
desc 'detect', 'detect the target OS'
|
177
|
+
target_options
|
178
|
+
option :format, type: :string
|
179
|
+
def detect
|
180
|
+
o = opts(:detect).dup
|
181
|
+
o[:command] = 'platform.params'
|
182
|
+
(_, res) = run_command(o)
|
183
|
+
if o['format'] == 'json'
|
184
|
+
puts res.to_json
|
185
|
+
else
|
186
|
+
headline('Platform Details')
|
187
|
+
puts Inspec::BaseCLI.detect(params: res, indent: 0, color: 36)
|
188
|
+
end
|
189
|
+
rescue ArgumentError, RuntimeError, Train::UserError => e
|
190
|
+
$stderr.puts e.message
|
191
|
+
exit 1
|
192
|
+
rescue StandardError => e
|
193
|
+
pretty_handle_exception(e)
|
194
|
+
end
|
195
|
+
|
196
|
+
desc 'shell', 'open an interactive debugging shell'
|
197
|
+
target_options
|
198
|
+
option :command, aliases: :c,
|
199
|
+
desc: 'A single command string to run instead of launching the shell'
|
200
|
+
option :format, type: :string, default: nil, hide: true,
|
201
|
+
desc: '[DEPRECATED] Please use --reporter - this will be removed in InSpec 3.0'
|
202
|
+
option :reporter, type: :array,
|
203
|
+
banner: 'one two:/output/file/path',
|
204
|
+
desc: 'Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit'
|
205
|
+
option :depends, type: :array, default: [],
|
206
|
+
desc: 'A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell'
|
207
|
+
def shell_func
|
208
|
+
o = opts(:shell).dup
|
209
|
+
diagnose(o)
|
210
|
+
o[:debug_shell] = true
|
211
|
+
|
212
|
+
log_device = suppress_log_output?(o) ? nil : STDOUT
|
213
|
+
o[:logger] = Logger.new(log_device)
|
214
|
+
o[:logger].level = get_log_level(o.log_level)
|
215
|
+
|
216
|
+
if o[:command].nil?
|
217
|
+
runner = Inspec::Runner.new(o)
|
218
|
+
return Inspec::Shell.new(runner).start
|
219
|
+
end
|
220
|
+
|
221
|
+
run_type, res = run_command(o)
|
222
|
+
exit res unless run_type == :ruby_eval
|
223
|
+
|
224
|
+
# No InSpec tests - just print evaluation output.
|
225
|
+
res = (res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)) if o['reporter']&.keys&.include?('json')
|
226
|
+
puts res
|
227
|
+
exit 0
|
228
|
+
rescue RuntimeError, Train::UserError => e
|
229
|
+
$stderr.puts e.message
|
230
|
+
rescue StandardError => e
|
231
|
+
pretty_handle_exception(e)
|
232
|
+
end
|
233
|
+
|
234
|
+
desc 'env', 'Output shell-appropriate completion configuration'
|
235
|
+
def env(shell = nil)
|
236
|
+
p = Inspec::EnvPrinter.new(self.class, shell)
|
237
|
+
p.print_and_exit!
|
238
|
+
rescue StandardError => e
|
239
|
+
pretty_handle_exception(e)
|
240
|
+
end
|
241
|
+
|
242
|
+
desc 'schema NAME', 'print the JSON schema', hide: true
|
243
|
+
def schema(name)
|
244
|
+
puts Inspec::Schema.json(name)
|
245
|
+
rescue StandardError => e
|
246
|
+
puts e
|
247
|
+
puts "Valid schemas are #{Inspec::Schema.names.join(', ')}"
|
248
|
+
end
|
249
|
+
|
250
|
+
desc 'version', 'prints the version of this tool'
|
251
|
+
option :format, type: :string
|
252
|
+
def version
|
253
|
+
if opts['format'] == 'json'
|
254
|
+
v = { version: Inspec::VERSION }
|
255
|
+
puts v.to_json
|
256
|
+
else
|
257
|
+
puts Inspec::VERSION
|
258
|
+
# display outdated version
|
259
|
+
latest = LatestInSpecVersion.new.latest
|
260
|
+
if Gem::Version.new(Inspec::VERSION) < Gem::Version.new(latest)
|
261
|
+
puts "\nYour version of InSpec is out of date! The latest version is #{latest}."
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
map %w{-v --version} => :version
|
266
|
+
|
267
|
+
private
|
268
|
+
|
269
|
+
def run_command(opts)
|
270
|
+
runner = Inspec::Runner.new(opts)
|
271
|
+
res = runner.eval_with_virtual_profile(opts[:command])
|
272
|
+
runner.load
|
273
|
+
|
274
|
+
return :ruby_eval, res if runner.all_rules.empty?
|
275
|
+
return :rspec_run, runner.run_tests # rubocop:disable Style/RedundantReturn
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Load all plugins on startup
|
280
|
+
ctl = Inspec::PluginCtl.new
|
281
|
+
ctl.list.each { |x| ctl.load(x) }
|
282
|
+
|
283
|
+
# load CLI plugins before the Inspec CLI has been started
|
284
|
+
Inspec::Plugins::CLI.subcommands.each { |_subcommand, params|
|
285
|
+
Inspec::InspecCLI.register(
|
286
|
+
params[:klass],
|
287
|
+
params[:subcommand_name],
|
288
|
+
params[:usage],
|
289
|
+
params[:description],
|
290
|
+
params[:options],
|
291
|
+
)
|
292
|
+
}
|