inspec 2.1.81 → 2.1.83
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 +5 -5
- data/.rubocop.yml +101 -101
- data/CHANGELOG.md +3183 -3177
- data/Gemfile +56 -56
- data/LICENSE +14 -14
- data/MAINTAINERS.md +33 -33
- data/MAINTAINERS.toml +52 -52
- data/README.md +453 -453
- data/Rakefile +349 -349
- data/bin/inspec +12 -12
- data/docs/.gitignore +2 -2
- data/docs/README.md +41 -40
- data/docs/dev/control-eval.md +61 -61
- data/docs/dsl_inspec.md +258 -258
- data/docs/dsl_resource.md +100 -100
- data/docs/glossary.md +99 -99
- data/docs/habitat.md +191 -191
- data/docs/inspec_and_friends.md +114 -114
- data/docs/matchers.md +169 -169
- data/docs/migration.md +293 -293
- data/docs/platforms.md +118 -118
- data/docs/plugin_kitchen_inspec.md +50 -50
- data/docs/profiles.md +378 -378
- data/docs/reporters.md +105 -105
- data/docs/resources/aide_conf.md.erb +75 -75
- data/docs/resources/apache.md.erb +67 -67
- data/docs/resources/apache_conf.md.erb +68 -68
- data/docs/resources/apt.md.erb +71 -71
- data/docs/resources/audit_policy.md.erb +47 -47
- data/docs/resources/auditd.md.erb +79 -79
- data/docs/resources/auditd_conf.md.erb +68 -68
- data/docs/resources/aws_cloudtrail_trail.md.erb +155 -155
- data/docs/resources/aws_cloudtrail_trails.md.erb +86 -86
- data/docs/resources/aws_cloudwatch_alarm.md.erb +91 -91
- data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +154 -154
- data/docs/resources/aws_config_delivery_channel.md.erb +101 -101
- data/docs/resources/aws_config_recorder.md.erb +86 -86
- data/docs/resources/aws_ec2_instance.md.erb +112 -112
- data/docs/resources/aws_ec2_instances.md.erb +79 -79
- data/docs/resources/aws_iam_access_key.md.erb +129 -129
- data/docs/resources/aws_iam_access_keys.md.erb +204 -204
- data/docs/resources/aws_iam_group.md.erb +64 -64
- data/docs/resources/aws_iam_groups.md.erb +49 -49
- data/docs/resources/aws_iam_password_policy.md.erb +82 -82
- data/docs/resources/aws_iam_policies.md.erb +87 -87
- data/docs/resources/aws_iam_policy.md.erb +245 -245
- data/docs/resources/aws_iam_role.md.erb +69 -69
- data/docs/resources/aws_iam_root_user.md.erb +76 -76
- data/docs/resources/aws_iam_user.md.erb +120 -120
- data/docs/resources/aws_iam_users.md.erb +279 -279
- data/docs/resources/aws_kms_key.md.erb +177 -177
- data/docs/resources/aws_kms_keys.md.erb +89 -89
- data/docs/resources/aws_rds_instance.md.erb +66 -66
- data/docs/resources/aws_route_table.md.erb +53 -53
- data/docs/resources/aws_route_tables.md.erb +55 -55
- data/docs/resources/aws_s3_bucket.md.erb +146 -146
- data/docs/resources/aws_s3_bucket_object.md.erb +89 -89
- data/docs/resources/aws_s3_buckets.md.erb +59 -59
- data/docs/resources/aws_security_group.md.erb +296 -296
- data/docs/resources/aws_security_groups.md.erb +97 -97
- data/docs/resources/aws_sns_subscription.md.erb +130 -130
- data/docs/resources/aws_sns_topic.md.erb +69 -69
- data/docs/resources/aws_sns_topics.md.erb +58 -58
- data/docs/resources/aws_subnet.md.erb +140 -140
- data/docs/resources/aws_subnets.md.erb +132 -132
- data/docs/resources/aws_vpc.md.erb +125 -125
- data/docs/resources/aws_vpcs.md.erb +125 -125
- data/docs/resources/azure_generic_resource.md.erb +171 -171
- data/docs/resources/azure_resource_group.md.erb +284 -284
- data/docs/resources/azure_virtual_machine.md.erb +347 -347
- data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
- data/docs/resources/bash.md.erb +75 -75
- data/docs/resources/bond.md.erb +90 -90
- data/docs/resources/bridge.md.erb +57 -57
- data/docs/resources/bsd_service.md.erb +67 -67
- data/docs/resources/chocolatey_package.md.erb +58 -58
- data/docs/resources/command.md.erb +138 -138
- data/docs/resources/cpan.md.erb +79 -79
- data/docs/resources/cran.md.erb +64 -64
- data/docs/resources/crontab.md.erb +89 -89
- data/docs/resources/csv.md.erb +54 -54
- data/docs/resources/dh_params.md.erb +205 -205
- data/docs/resources/directory.md.erb +30 -30
- data/docs/resources/docker.md.erb +219 -219
- data/docs/resources/docker_container.md.erb +103 -103
- data/docs/resources/docker_image.md.erb +94 -94
- data/docs/resources/docker_service.md.erb +114 -114
- data/docs/resources/elasticsearch.md.erb +242 -242
- data/docs/resources/etc_fstab.md.erb +125 -125
- data/docs/resources/etc_group.md.erb +75 -75
- data/docs/resources/etc_hosts.md.erb +78 -78
- data/docs/resources/etc_hosts_allow.md.erb +74 -74
- data/docs/resources/etc_hosts_deny.md.erb +74 -74
- data/docs/resources/file.md.erb +526 -526
- data/docs/resources/filesystem.md.erb +41 -41
- data/docs/resources/firewalld.md.erb +107 -107
- data/docs/resources/gem.md.erb +79 -79
- data/docs/resources/group.md.erb +61 -61
- data/docs/resources/grub_conf.md.erb +101 -101
- data/docs/resources/host.md.erb +86 -86
- data/docs/resources/http.md.erb +197 -197
- data/docs/resources/iis_app.md.erb +122 -122
- data/docs/resources/iis_site.md.erb +135 -135
- data/docs/resources/inetd_conf.md.erb +94 -94
- data/docs/resources/ini.md.erb +76 -76
- data/docs/resources/interface.md.erb +58 -58
- data/docs/resources/iptables.md.erb +64 -64
- data/docs/resources/json.md.erb +63 -63
- data/docs/resources/kernel_module.md.erb +120 -120
- data/docs/resources/kernel_parameter.md.erb +53 -53
- data/docs/resources/key_rsa.md.erb +85 -85
- data/docs/resources/launchd_service.md.erb +57 -57
- data/docs/resources/limits_conf.md.erb +75 -75
- data/docs/resources/login_defs.md.erb +71 -71
- data/docs/resources/mount.md.erb +69 -69
- data/docs/resources/mssql_session.md.erb +60 -60
- data/docs/resources/mysql_conf.md.erb +99 -99
- data/docs/resources/mysql_session.md.erb +74 -74
- data/docs/resources/nginx.md.erb +79 -79
- data/docs/resources/nginx_conf.md.erb +138 -138
- data/docs/resources/npm.md.erb +60 -60
- data/docs/resources/ntp_conf.md.erb +60 -60
- data/docs/resources/oneget.md.erb +53 -53
- data/docs/resources/oracledb_session.md.erb +52 -52
- data/docs/resources/os.md.erb +141 -141
- data/docs/resources/os_env.md.erb +91 -91
- data/docs/resources/package.md.erb +120 -120
- data/docs/resources/packages.md.erb +67 -67
- data/docs/resources/parse_config.md.erb +103 -103
- data/docs/resources/parse_config_file.md.erb +138 -138
- data/docs/resources/passwd.md.erb +141 -141
- data/docs/resources/pip.md.erb +67 -67
- data/docs/resources/port.md.erb +137 -137
- data/docs/resources/postgres_conf.md.erb +79 -79
- data/docs/resources/postgres_hba_conf.md.erb +93 -93
- data/docs/resources/postgres_ident_conf.md.erb +76 -76
- data/docs/resources/postgres_session.md.erb +69 -69
- data/docs/resources/powershell.md.erb +102 -102
- data/docs/resources/processes.md.erb +109 -109
- data/docs/resources/rabbitmq_config.md.erb +41 -41
- data/docs/resources/registry_key.md.erb +158 -158
- data/docs/resources/runit_service.md.erb +57 -57
- data/docs/resources/security_policy.md.erb +47 -47
- data/docs/resources/service.md.erb +121 -121
- data/docs/resources/shadow.md.erb +146 -146
- data/docs/resources/ssh_config.md.erb +73 -73
- data/docs/resources/sshd_config.md.erb +83 -83
- data/docs/resources/ssl.md.erb +119 -119
- data/docs/resources/sys_info.md.erb +42 -42
- data/docs/resources/systemd_service.md.erb +57 -57
- data/docs/resources/sysv_service.md.erb +57 -57
- data/docs/resources/upstart_service.md.erb +57 -57
- data/docs/resources/user.md.erb +140 -140
- data/docs/resources/users.md.erb +127 -127
- data/docs/resources/vbscript.md.erb +55 -55
- data/docs/resources/virtualization.md.erb +57 -57
- data/docs/resources/windows_feature.md.erb +47 -47
- data/docs/resources/windows_hotfix.md.erb +53 -53
- data/docs/resources/windows_task.md.erb +95 -95
- data/docs/resources/wmi.md.erb +81 -81
- data/docs/resources/x509_certificate.md.erb +151 -151
- data/docs/resources/xinetd_conf.md.erb +156 -156
- data/docs/resources/xml.md.erb +85 -85
- data/docs/resources/yaml.md.erb +69 -69
- data/docs/resources/yum.md.erb +98 -98
- data/docs/resources/zfs_dataset.md.erb +53 -53
- data/docs/resources/zfs_pool.md.erb +47 -47
- data/docs/ruby_usage.md +203 -203
- data/docs/shared/matcher_be.md.erb +1 -1
- data/docs/shared/matcher_cmp.md.erb +43 -43
- data/docs/shared/matcher_eq.md.erb +3 -3
- data/docs/shared/matcher_include.md.erb +1 -1
- data/docs/shared/matcher_match.md.erb +1 -1
- data/docs/shell.md +217 -217
- data/examples/README.md +8 -8
- data/examples/inheritance/README.md +65 -65
- data/examples/inheritance/controls/example.rb +14 -14
- data/examples/inheritance/inspec.yml +15 -15
- data/examples/kitchen-ansible/.kitchen.yml +25 -25
- data/examples/kitchen-ansible/Gemfile +19 -19
- data/examples/kitchen-ansible/README.md +53 -53
- data/examples/kitchen-ansible/files/nginx.repo +6 -6
- data/examples/kitchen-ansible/tasks/main.yml +16 -16
- data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
- data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
- data/examples/kitchen-chef/.kitchen.yml +20 -20
- data/examples/kitchen-chef/Berksfile +3 -3
- data/examples/kitchen-chef/Gemfile +19 -19
- data/examples/kitchen-chef/README.md +27 -27
- data/examples/kitchen-chef/metadata.rb +7 -7
- data/examples/kitchen-chef/recipes/default.rb +6 -6
- data/examples/kitchen-chef/recipes/nginx.rb +30 -30
- data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
- data/examples/kitchen-puppet/.kitchen.yml +23 -23
- data/examples/kitchen-puppet/Gemfile +20 -20
- data/examples/kitchen-puppet/Puppetfile +25 -25
- data/examples/kitchen-puppet/README.md +53 -53
- data/examples/kitchen-puppet/manifests/site.pp +33 -33
- data/examples/kitchen-puppet/metadata.json +11 -11
- data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
- data/examples/meta-profile/README.md +37 -37
- data/examples/meta-profile/controls/example.rb +13 -13
- data/examples/meta-profile/inspec.yml +13 -13
- data/examples/profile-attribute.yml +2 -2
- data/examples/profile-attribute/README.md +14 -14
- data/examples/profile-attribute/controls/example.rb +11 -11
- data/examples/profile-attribute/inspec.yml +8 -8
- data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
- data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
- data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
- data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
- data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
- data/examples/profile-aws/inspec.yml +11 -11
- data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
- data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
- data/examples/profile-azure/inspec.yml +11 -11
- data/examples/profile-sensitive/README.md +29 -29
- data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
- data/examples/profile-sensitive/controls/sensitive.rb +9 -9
- data/examples/profile-sensitive/inspec.yml +8 -8
- data/examples/profile/README.md +48 -48
- data/examples/profile/controls/example.rb +23 -23
- data/examples/profile/controls/gordon.rb +36 -36
- data/examples/profile/controls/meta.rb +34 -34
- data/examples/profile/inspec.yml +10 -10
- data/examples/profile/libraries/gordon_config.rb +59 -59
- data/inspec.gemspec +49 -49
- data/lib/bundles/README.md +3 -3
- data/lib/bundles/inspec-artifact.rb +7 -7
- data/lib/bundles/inspec-artifact/README.md +1 -1
- data/lib/bundles/inspec-artifact/cli.rb +277 -277
- data/lib/bundles/inspec-compliance.rb +16 -16
- data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
- data/lib/bundles/inspec-compliance/README.md +193 -193
- data/lib/bundles/inspec-compliance/api.rb +360 -360
- data/lib/bundles/inspec-compliance/api/login.rb +193 -193
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
- data/lib/bundles/inspec-compliance/cli.rb +260 -260
- data/lib/bundles/inspec-compliance/configuration.rb +103 -103
- data/lib/bundles/inspec-compliance/http.rb +125 -125
- data/lib/bundles/inspec-compliance/support.rb +36 -36
- data/lib/bundles/inspec-compliance/target.rb +112 -112
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
- data/lib/bundles/inspec-habitat.rb +12 -12
- data/lib/bundles/inspec-habitat/cli.rb +36 -36
- data/lib/bundles/inspec-habitat/log.rb +10 -10
- data/lib/bundles/inspec-habitat/profile.rb +391 -391
- data/lib/bundles/inspec-init.rb +8 -8
- data/lib/bundles/inspec-init/README.md +31 -31
- data/lib/bundles/inspec-init/cli.rb +97 -97
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
- data/lib/bundles/inspec-supermarket.rb +13 -13
- data/lib/bundles/inspec-supermarket/README.md +45 -45
- data/lib/bundles/inspec-supermarket/api.rb +84 -84
- data/lib/bundles/inspec-supermarket/cli.rb +73 -73
- data/lib/bundles/inspec-supermarket/target.rb +34 -34
- data/lib/fetchers/git.rb +163 -163
- data/lib/fetchers/local.rb +74 -74
- data/lib/fetchers/mock.rb +35 -35
- data/lib/fetchers/url.rb +247 -247
- data/lib/inspec.rb +24 -24
- data/lib/inspec/archive/tar.rb +29 -29
- data/lib/inspec/archive/zip.rb +19 -19
- data/lib/inspec/backend.rb +93 -93
- data/lib/inspec/base_cli.rb +368 -368
- data/lib/inspec/cached_fetcher.rb +66 -66
- data/lib/inspec/cli.rb +292 -292
- data/lib/inspec/completions/bash.sh.erb +45 -45
- data/lib/inspec/completions/fish.sh.erb +34 -34
- data/lib/inspec/completions/zsh.sh.erb +61 -61
- data/lib/inspec/control_eval_context.rb +179 -179
- data/lib/inspec/dependencies/cache.rb +72 -72
- data/lib/inspec/dependencies/dependency_set.rb +92 -92
- data/lib/inspec/dependencies/lockfile.rb +115 -115
- data/lib/inspec/dependencies/requirement.rb +123 -123
- data/lib/inspec/dependencies/resolver.rb +86 -86
- data/lib/inspec/describe.rb +27 -27
- data/lib/inspec/dsl.rb +66 -66
- data/lib/inspec/dsl_shared.rb +33 -33
- data/lib/inspec/env_printer.rb +157 -157
- data/lib/inspec/errors.rb +14 -14
- data/lib/inspec/exceptions.rb +12 -12
- data/lib/inspec/expect.rb +45 -45
- data/lib/inspec/fetcher.rb +45 -45
- data/lib/inspec/file_provider.rb +275 -275
- data/lib/inspec/formatters.rb +3 -3
- data/lib/inspec/formatters/base.rb +259 -259
- data/lib/inspec/formatters/json_rspec.rb +20 -20
- data/lib/inspec/formatters/show_progress.rb +12 -12
- data/lib/inspec/library_eval_context.rb +58 -58
- data/lib/inspec/log.rb +11 -11
- data/lib/inspec/metadata.rb +247 -247
- data/lib/inspec/method_source.rb +24 -24
- data/lib/inspec/objects.rb +14 -14
- data/lib/inspec/objects/attribute.rb +75 -75
- data/lib/inspec/objects/control.rb +61 -61
- data/lib/inspec/objects/describe.rb +92 -92
- data/lib/inspec/objects/each_loop.rb +36 -36
- data/lib/inspec/objects/list.rb +15 -15
- data/lib/inspec/objects/or_test.rb +40 -40
- data/lib/inspec/objects/ruby_helper.rb +15 -15
- data/lib/inspec/objects/tag.rb +27 -27
- data/lib/inspec/objects/test.rb +87 -87
- data/lib/inspec/objects/value.rb +27 -27
- data/lib/inspec/plugins.rb +60 -60
- data/lib/inspec/plugins/cli.rb +24 -24
- data/lib/inspec/plugins/fetcher.rb +86 -86
- data/lib/inspec/plugins/resource.rb +135 -135
- data/lib/inspec/plugins/secret.rb +15 -15
- data/lib/inspec/plugins/source_reader.rb +40 -40
- data/lib/inspec/polyfill.rb +12 -12
- data/lib/inspec/profile.rb +513 -513
- data/lib/inspec/profile_context.rb +208 -208
- data/lib/inspec/profile_vendor.rb +66 -66
- data/lib/inspec/reporters.rb +60 -60
- data/lib/inspec/reporters/automate.rb +76 -76
- data/lib/inspec/reporters/base.rb +25 -25
- data/lib/inspec/reporters/cli.rb +356 -356
- data/lib/inspec/reporters/json.rb +117 -117
- data/lib/inspec/reporters/json_min.rb +48 -48
- data/lib/inspec/reporters/junit.rb +78 -78
- data/lib/inspec/require_loader.rb +33 -33
- data/lib/inspec/resource.rb +190 -190
- data/lib/inspec/rule.rb +280 -280
- data/lib/inspec/runner.rb +345 -345
- data/lib/inspec/runner_mock.rb +41 -41
- data/lib/inspec/runner_rspec.rb +175 -175
- data/lib/inspec/runtime_profile.rb +26 -26
- data/lib/inspec/schema.rb +213 -213
- data/lib/inspec/secrets.rb +19 -19
- data/lib/inspec/secrets/yaml.rb +30 -30
- data/lib/inspec/shell.rb +220 -220
- data/lib/inspec/shell_detector.rb +90 -90
- data/lib/inspec/source_reader.rb +29 -29
- data/lib/inspec/version.rb +8 -8
- data/lib/matchers/matchers.rb +339 -339
- data/lib/resource_support/aws.rb +50 -50
- data/lib/resource_support/aws/aws_backend_base.rb +12 -12
- data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
- data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
- data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
- data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
- data/lib/resources/aide_conf.rb +151 -151
- data/lib/resources/apache.rb +48 -48
- data/lib/resources/apache_conf.rb +149 -149
- data/lib/resources/apt.rb +149 -149
- data/lib/resources/audit_policy.rb +63 -63
- data/lib/resources/auditd.rb +231 -231
- data/lib/resources/auditd_conf.rb +46 -46
- data/lib/resources/aws/aws_cloudtrail_trail.rb +93 -93
- data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
- data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
- data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
- data/lib/resources/aws/aws_config_delivery_channel.rb +70 -70
- data/lib/resources/aws/aws_config_recorder.rb +93 -93
- data/lib/resources/aws/aws_ec2_instance.rb +157 -157
- data/lib/resources/aws/aws_ec2_instances.rb +64 -64
- data/lib/resources/aws/aws_iam_access_key.rb +106 -106
- data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
- data/lib/resources/aws/aws_iam_group.rb +58 -58
- data/lib/resources/aws/aws_iam_groups.rb +52 -52
- data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
- data/lib/resources/aws/aws_iam_policies.rb +53 -53
- data/lib/resources/aws/aws_iam_policy.rb +291 -291
- data/lib/resources/aws/aws_iam_role.rb +55 -55
- data/lib/resources/aws/aws_iam_root_user.rb +78 -78
- data/lib/resources/aws/aws_iam_user.rb +142 -142
- data/lib/resources/aws/aws_iam_users.rb +146 -146
- data/lib/resources/aws/aws_kms_key.rb +96 -96
- data/lib/resources/aws/aws_kms_keys.rb +53 -53
- data/lib/resources/aws/aws_rds_instance.rb +71 -71
- data/lib/resources/aws/aws_route_table.rb +63 -63
- data/lib/resources/aws/aws_route_tables.rb +60 -60
- data/lib/resources/aws/aws_s3_bucket.rb +137 -137
- data/lib/resources/aws/aws_s3_bucket_object.rb +82 -82
- data/lib/resources/aws/aws_s3_buckets.rb +51 -51
- data/lib/resources/aws/aws_security_group.rb +249 -249
- data/lib/resources/aws/aws_security_groups.rb +68 -68
- data/lib/resources/aws/aws_sns_subscription.rb +78 -78
- data/lib/resources/aws/aws_sns_topic.rb +53 -53
- data/lib/resources/aws/aws_sns_topics.rb +56 -56
- data/lib/resources/aws/aws_subnet.rb +88 -88
- data/lib/resources/aws/aws_subnets.rb +53 -53
- data/lib/resources/aws/aws_vpc.rb +73 -73
- data/lib/resources/aws/aws_vpcs.rb +52 -52
- data/lib/resources/azure/azure_backend.rb +377 -377
- data/lib/resources/azure/azure_generic_resource.rb +59 -59
- data/lib/resources/azure/azure_resource_group.rb +152 -152
- data/lib/resources/azure/azure_virtual_machine.rb +264 -264
- data/lib/resources/azure/azure_virtual_machine_data_disk.rb +134 -134
- data/lib/resources/bash.rb +35 -35
- data/lib/resources/bond.rb +69 -69
- data/lib/resources/bridge.rb +122 -122
- data/lib/resources/chocolatey_package.rb +78 -78
- data/lib/resources/command.rb +73 -73
- data/lib/resources/cpan.rb +58 -58
- data/lib/resources/cran.rb +64 -64
- data/lib/resources/crontab.rb +169 -169
- data/lib/resources/csv.rb +56 -56
- data/lib/resources/dh_params.rb +77 -77
- data/lib/resources/directory.rb +25 -25
- data/lib/resources/docker.rb +236 -236
- data/lib/resources/docker_container.rb +89 -89
- data/lib/resources/docker_image.rb +83 -83
- data/lib/resources/docker_object.rb +57 -57
- data/lib/resources/docker_service.rb +90 -90
- data/lib/resources/elasticsearch.rb +169 -169
- data/lib/resources/etc_fstab.rb +94 -94
- data/lib/resources/etc_group.rb +154 -154
- data/lib/resources/etc_hosts.rb +66 -66
- data/lib/resources/etc_hosts_allow_deny.rb +112 -112
- data/lib/resources/file.rb +298 -298
- data/lib/resources/filesystem.rb +31 -31
- data/lib/resources/firewalld.rb +143 -143
- data/lib/resources/gem.rb +70 -70
- data/lib/resources/groups.rb +215 -215
- data/lib/resources/grub_conf.rb +227 -227
- data/lib/resources/host.rb +306 -306
- data/lib/resources/http.rb +253 -253
- data/lib/resources/iis_app.rb +101 -101
- data/lib/resources/iis_site.rb +148 -148
- data/lib/resources/inetd_conf.rb +54 -54
- data/lib/resources/ini.rb +29 -29
- data/lib/resources/interface.rb +129 -129
- data/lib/resources/iptables.rb +80 -80
- data/lib/resources/json.rb +111 -111
- data/lib/resources/kernel_module.rb +107 -107
- data/lib/resources/kernel_parameter.rb +58 -58
- data/lib/resources/key_rsa.rb +63 -63
- data/lib/resources/limits_conf.rb +46 -46
- data/lib/resources/login_def.rb +57 -57
- data/lib/resources/mount.rb +88 -88
- data/lib/resources/mssql_session.rb +101 -101
- data/lib/resources/mysql.rb +82 -82
- data/lib/resources/mysql_conf.rb +127 -127
- data/lib/resources/mysql_session.rb +85 -85
- data/lib/resources/nginx.rb +96 -96
- data/lib/resources/nginx_conf.rb +226 -226
- data/lib/resources/npm.rb +48 -48
- data/lib/resources/ntp_conf.rb +51 -51
- data/lib/resources/oneget.rb +71 -71
- data/lib/resources/oracledb_session.rb +139 -139
- data/lib/resources/os.rb +36 -36
- data/lib/resources/os_env.rb +86 -86
- data/lib/resources/package.rb +370 -370
- data/lib/resources/packages.rb +111 -111
- data/lib/resources/parse_config.rb +112 -112
- data/lib/resources/passwd.rb +76 -76
- data/lib/resources/pip.rb +130 -130
- data/lib/resources/platform.rb +109 -109
- data/lib/resources/port.rb +771 -771
- data/lib/resources/postgres.rb +131 -131
- data/lib/resources/postgres_conf.rb +114 -114
- data/lib/resources/postgres_hba_conf.rb +90 -90
- data/lib/resources/postgres_ident_conf.rb +79 -79
- data/lib/resources/postgres_session.rb +71 -71
- data/lib/resources/powershell.rb +67 -67
- data/lib/resources/processes.rb +204 -204
- data/lib/resources/rabbitmq_conf.rb +51 -51
- data/lib/resources/registry_key.rb +297 -297
- data/lib/resources/security_policy.rb +180 -180
- data/lib/resources/service.rb +794 -794
- data/lib/resources/shadow.rb +159 -159
- data/lib/resources/ssh_conf.rb +97 -97
- data/lib/resources/ssl.rb +99 -99
- data/lib/resources/sys_info.rb +28 -28
- data/lib/resources/toml.rb +32 -32
- data/lib/resources/users.rb +654 -654
- data/lib/resources/vbscript.rb +68 -68
- data/lib/resources/virtualization.rb +247 -247
- data/lib/resources/windows_feature.rb +84 -84
- data/lib/resources/windows_hotfix.rb +35 -35
- data/lib/resources/windows_task.rb +102 -102
- data/lib/resources/wmi.rb +110 -110
- data/lib/resources/x509_certificate.rb +137 -137
- data/lib/resources/xinetd.rb +106 -106
- data/lib/resources/xml.rb +46 -46
- data/lib/resources/yaml.rb +43 -43
- data/lib/resources/yum.rb +180 -180
- data/lib/resources/zfs_dataset.rb +60 -60
- data/lib/resources/zfs_pool.rb +49 -49
- data/lib/source_readers/flat.rb +39 -39
- data/lib/source_readers/inspec.rb +75 -75
- data/lib/utils/command_wrapper.rb +27 -27
- data/lib/utils/convert.rb +12 -12
- data/lib/utils/database_helpers.rb +77 -77
- data/lib/utils/enumerable_delegation.rb +9 -9
- data/lib/utils/erlang_parser.rb +192 -192
- data/lib/utils/file_reader.rb +25 -25
- data/lib/utils/filter.rb +273 -273
- data/lib/utils/filter_array.rb +27 -27
- data/lib/utils/find_files.rb +47 -47
- data/lib/utils/hash.rb +41 -41
- data/lib/utils/json_log.rb +18 -18
- data/lib/utils/latest_version.rb +22 -22
- data/lib/utils/modulator.rb +12 -12
- data/lib/utils/nginx_parser.rb +105 -105
- data/lib/utils/object_traversal.rb +49 -49
- data/lib/utils/parser.rb +274 -274
- data/lib/utils/pkey_reader.rb +15 -15
- data/lib/utils/plugin_registry.rb +93 -93
- data/lib/utils/simpleconfig.rb +120 -120
- data/lib/utils/spdx.rb +13 -13
- data/lib/utils/spdx.txt +343 -343
- metadata +3 -3
data/lib/inspec.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# copyright: 2015, Dominik Richter
|
3
|
-
# author: Dominik Richter
|
4
|
-
# author: Christoph Hartmann
|
5
|
-
|
6
|
-
libdir = File.dirname(__FILE__)
|
7
|
-
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
8
|
-
|
9
|
-
require 'inspec/version'
|
10
|
-
require 'inspec/exceptions'
|
11
|
-
require 'inspec/profile'
|
12
|
-
require 'inspec/rule'
|
13
|
-
require 'matchers/matchers'
|
14
|
-
require 'inspec/runner'
|
15
|
-
require 'inspec/shell'
|
16
|
-
require 'inspec/formatters'
|
17
|
-
require 'inspec/reporters'
|
18
|
-
|
19
|
-
# all utils that may be required by plugins
|
20
|
-
require 'inspec/base_cli'
|
21
|
-
require 'inspec/fetcher'
|
22
|
-
require 'inspec/source_reader'
|
23
|
-
require 'inspec/resource'
|
24
|
-
require 'inspec/plugins'
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, Dominik Richter
|
3
|
+
# author: Dominik Richter
|
4
|
+
# author: Christoph Hartmann
|
5
|
+
|
6
|
+
libdir = File.dirname(__FILE__)
|
7
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
8
|
+
|
9
|
+
require 'inspec/version'
|
10
|
+
require 'inspec/exceptions'
|
11
|
+
require 'inspec/profile'
|
12
|
+
require 'inspec/rule'
|
13
|
+
require 'matchers/matchers'
|
14
|
+
require 'inspec/runner'
|
15
|
+
require 'inspec/shell'
|
16
|
+
require 'inspec/formatters'
|
17
|
+
require 'inspec/reporters'
|
18
|
+
|
19
|
+
# all utils that may be required by plugins
|
20
|
+
require 'inspec/base_cli'
|
21
|
+
require 'inspec/fetcher'
|
22
|
+
require 'inspec/source_reader'
|
23
|
+
require 'inspec/resource'
|
24
|
+
require 'inspec/plugins'
|
data/lib/inspec/archive/tar.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# author: Christoph Hartmann
|
3
|
-
# author: Dominik Richter
|
4
|
-
|
5
|
-
require 'rubygems/package'
|
6
|
-
|
7
|
-
module Inspec::Archive
|
8
|
-
class TarArchiveGenerator
|
9
|
-
def archive(base_dir, files, archive)
|
10
|
-
File.open(archive, 'wb') do |file|
|
11
|
-
Zlib::GzipWriter.wrap(file) do |gz|
|
12
|
-
Gem::Package::TarWriter.new(gz) do |tar|
|
13
|
-
files.each do |input_filename|
|
14
|
-
path = Pathname.new(base_dir).join(input_filename)
|
15
|
-
stat = File.stat(path)
|
16
|
-
if path.directory?
|
17
|
-
tar.mkdir(input_filename, stat.mode)
|
18
|
-
else
|
19
|
-
tar.add_file_simple(input_filename, stat.mode, stat.size) do |io|
|
20
|
-
io.write(File.binread(path))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
require 'rubygems/package'
|
6
|
+
|
7
|
+
module Inspec::Archive
|
8
|
+
class TarArchiveGenerator
|
9
|
+
def archive(base_dir, files, archive)
|
10
|
+
File.open(archive, 'wb') do |file|
|
11
|
+
Zlib::GzipWriter.wrap(file) do |gz|
|
12
|
+
Gem::Package::TarWriter.new(gz) do |tar|
|
13
|
+
files.each do |input_filename|
|
14
|
+
path = Pathname.new(base_dir).join(input_filename)
|
15
|
+
stat = File.stat(path)
|
16
|
+
if path.directory?
|
17
|
+
tar.mkdir(input_filename, stat.mode)
|
18
|
+
else
|
19
|
+
tar.add_file_simple(input_filename, stat.mode, stat.size) do |io|
|
20
|
+
io.write(File.binread(path))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/inspec/archive/zip.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# author: Christoph Hartmann
|
3
|
-
# author: Dominik Richter
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'zip'
|
7
|
-
require 'pathname'
|
8
|
-
|
9
|
-
module Inspec::Archive
|
10
|
-
class ZipArchiveGenerator
|
11
|
-
def archive(base_dir, files, archive)
|
12
|
-
Zip::File.open(archive, Zip::File::CREATE) do |zipfile|
|
13
|
-
files.each do |input_filename|
|
14
|
-
zipfile.add(input_filename, Pathname.new(base_dir).join(input_filename))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'zip'
|
7
|
+
require 'pathname'
|
8
|
+
|
9
|
+
module Inspec::Archive
|
10
|
+
class ZipArchiveGenerator
|
11
|
+
def archive(base_dir, files, archive)
|
12
|
+
Zip::File.open(archive, Zip::File::CREATE) do |zipfile|
|
13
|
+
files.each do |input_filename|
|
14
|
+
zipfile.add(input_filename, Pathname.new(base_dir).join(input_filename))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/inspec/backend.rb
CHANGED
@@ -1,93 +1,93 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# copyright: 2015, Dominik Richter
|
3
|
-
# author: Dominik Richter
|
4
|
-
# author: Christoph Hartmann
|
5
|
-
|
6
|
-
require 'train'
|
7
|
-
|
8
|
-
module Inspec
|
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
|
-
# Determine whether the connection/transport is a local connection
|
21
|
-
# Useful for resources to modify behavior as necessary, such as using
|
22
|
-
# the Ruby stdlib for a better experience.
|
23
|
-
def local_transport?
|
24
|
-
return false unless defined?(Train::Transports::Local)
|
25
|
-
backend.is_a?(Train::Transports::Local::Connection)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Ruby internal for printing a nice name for this class
|
29
|
-
def to_s
|
30
|
-
'Inspec::Backend::Class'
|
31
|
-
end
|
32
|
-
|
33
|
-
# Ruby internal for pretty-printing a summary for this class
|
34
|
-
def inspect
|
35
|
-
"Inspec::Backend::Class @transport=#{backend.class}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Create the transport backend with aggregated resources.
|
40
|
-
#
|
41
|
-
# @param [Hash] config for the transport backend
|
42
|
-
# @return [TransportBackend] enriched transport instance
|
43
|
-
def self.create(config) # rubocop:disable Metrics/AbcSize
|
44
|
-
conf = Train.target_config(config)
|
45
|
-
name = Train.validate_backend(conf)
|
46
|
-
transport = Train.create(name, conf)
|
47
|
-
if transport.nil?
|
48
|
-
raise "Can't find transport backend '#{name}'."
|
49
|
-
end
|
50
|
-
|
51
|
-
connection = transport.connection
|
52
|
-
if connection.nil?
|
53
|
-
raise "Can't connect to transport backend '#{name}'."
|
54
|
-
end
|
55
|
-
|
56
|
-
# Set caching settings. We always want to enable caching for
|
57
|
-
# the Mock transport for testing.
|
58
|
-
if config[:backend_cache] || config[:backend] == :mock
|
59
|
-
Inspec::Log.debug 'Option backend_cache is enabled'
|
60
|
-
connection.enable_cache(:file)
|
61
|
-
connection.enable_cache(:command)
|
62
|
-
elsif config[:debug_shell]
|
63
|
-
Inspec::Log.debug 'Option backend_cache is disabled'
|
64
|
-
connection.disable_cache(:file)
|
65
|
-
connection.disable_cache(:command)
|
66
|
-
else
|
67
|
-
Inspec::Log.debug 'Option backend_cache is disabled'
|
68
|
-
connection.disable_cache(:file)
|
69
|
-
connection.disable_cache(:command)
|
70
|
-
end
|
71
|
-
|
72
|
-
cls = Class.new do
|
73
|
-
include Base
|
74
|
-
|
75
|
-
define_method :backend do
|
76
|
-
connection
|
77
|
-
end
|
78
|
-
|
79
|
-
Inspec::Resource.registry.each do |id, r|
|
80
|
-
define_method id.to_sym do |*args|
|
81
|
-
r.new(self, id.to_s, *args)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
cls.new
|
87
|
-
rescue Train::ClientError => e
|
88
|
-
raise "Client error, can't connect to '#{name}' backend: #{e.message}"
|
89
|
-
rescue Train::TransportError => e
|
90
|
-
raise "Transport error, can't connect to '#{name}' backend: #{e.message}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, Dominik Richter
|
3
|
+
# author: Dominik Richter
|
4
|
+
# author: Christoph Hartmann
|
5
|
+
|
6
|
+
require 'train'
|
7
|
+
|
8
|
+
module Inspec
|
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
|
+
# Determine whether the connection/transport is a local connection
|
21
|
+
# Useful for resources to modify behavior as necessary, such as using
|
22
|
+
# the Ruby stdlib for a better experience.
|
23
|
+
def local_transport?
|
24
|
+
return false unless defined?(Train::Transports::Local)
|
25
|
+
backend.is_a?(Train::Transports::Local::Connection)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Ruby internal for printing a nice name for this class
|
29
|
+
def to_s
|
30
|
+
'Inspec::Backend::Class'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Ruby internal for pretty-printing a summary for this class
|
34
|
+
def inspect
|
35
|
+
"Inspec::Backend::Class @transport=#{backend.class}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Create the transport backend with aggregated resources.
|
40
|
+
#
|
41
|
+
# @param [Hash] config for the transport backend
|
42
|
+
# @return [TransportBackend] enriched transport instance
|
43
|
+
def self.create(config) # rubocop:disable Metrics/AbcSize
|
44
|
+
conf = Train.target_config(config)
|
45
|
+
name = Train.validate_backend(conf)
|
46
|
+
transport = Train.create(name, conf)
|
47
|
+
if transport.nil?
|
48
|
+
raise "Can't find transport backend '#{name}'."
|
49
|
+
end
|
50
|
+
|
51
|
+
connection = transport.connection
|
52
|
+
if connection.nil?
|
53
|
+
raise "Can't connect to transport backend '#{name}'."
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set caching settings. We always want to enable caching for
|
57
|
+
# the Mock transport for testing.
|
58
|
+
if config[:backend_cache] || config[:backend] == :mock
|
59
|
+
Inspec::Log.debug 'Option backend_cache is enabled'
|
60
|
+
connection.enable_cache(:file)
|
61
|
+
connection.enable_cache(:command)
|
62
|
+
elsif config[:debug_shell]
|
63
|
+
Inspec::Log.debug 'Option backend_cache is disabled'
|
64
|
+
connection.disable_cache(:file)
|
65
|
+
connection.disable_cache(:command)
|
66
|
+
else
|
67
|
+
Inspec::Log.debug 'Option backend_cache is disabled'
|
68
|
+
connection.disable_cache(:file)
|
69
|
+
connection.disable_cache(:command)
|
70
|
+
end
|
71
|
+
|
72
|
+
cls = Class.new do
|
73
|
+
include Base
|
74
|
+
|
75
|
+
define_method :backend do
|
76
|
+
connection
|
77
|
+
end
|
78
|
+
|
79
|
+
Inspec::Resource.registry.each do |id, r|
|
80
|
+
define_method id.to_sym do |*args|
|
81
|
+
r.new(self, id.to_s, *args)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
cls.new
|
87
|
+
rescue Train::ClientError => e
|
88
|
+
raise "Client error, can't connect to '#{name}' backend: #{e.message}"
|
89
|
+
rescue Train::TransportError => e
|
90
|
+
raise "Transport error, can't connect to '#{name}' backend: #{e.message}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -1,368 +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
|
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
|