inspec 2.0.32 → 2.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +101 -101
- data/CHANGELOG.md +2991 -2970
- data/Gemfile +55 -55
- data/LICENSE +14 -14
- data/MAINTAINERS.md +33 -33
- data/MAINTAINERS.toml +52 -52
- data/README.md +446 -437
- data/Rakefile +322 -322
- data/bin/inspec +12 -12
- data/docs/.gitignore +2 -2
- data/docs/README.md +40 -40
- data/docs/dsl_inspec.md +258 -258
- data/docs/dsl_resource.md +93 -93
- data/docs/glossary.md +99 -99
- data/docs/habitat.md +191 -191
- data/docs/inspec_and_friends.md +107 -107
- data/docs/matchers.md +169 -168
- data/docs/migration.md +293 -293
- data/docs/platforms.md +118 -118
- data/docs/plugin_kitchen_inspec.md +49 -49
- data/docs/profiles.md +370 -370
- 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 +140 -140
- data/docs/resources/aws_cloudtrail_trails.md.erb +81 -81
- data/docs/resources/aws_cloudwatch_alarm.md.erb +86 -86
- data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +151 -151
- data/docs/resources/aws_config_recorder.md.erb +71 -71
- data/docs/resources/aws_ec2_instance.md.erb +106 -106
- data/docs/resources/aws_iam_access_key.md.erb +123 -123
- data/docs/resources/aws_iam_access_keys.md.erb +198 -198
- data/docs/resources/aws_iam_group.md.erb +46 -46
- data/docs/resources/aws_iam_groups.md.erb +43 -43
- data/docs/resources/aws_iam_password_policy.md.erb +76 -76
- data/docs/resources/aws_iam_policies.md.erb +82 -82
- data/docs/resources/aws_iam_policy.md.erb +144 -144
- data/docs/resources/aws_iam_role.md.erb +63 -63
- data/docs/resources/aws_iam_root_user.md.erb +58 -58
- data/docs/resources/aws_iam_user.md.erb +64 -64
- data/docs/resources/aws_iam_users.md.erb +89 -89
- data/docs/resources/aws_kms_keys.md.erb +84 -84
- data/docs/resources/aws_route_table.md.erb +47 -47
- data/docs/resources/aws_s3_bucket.md.erb +134 -134
- data/docs/resources/aws_security_group.md.erb +151 -151
- data/docs/resources/aws_security_groups.md.erb +91 -91
- data/docs/resources/aws_sns_topic.md.erb +63 -63
- data/docs/resources/aws_subnet.md.erb +133 -133
- data/docs/resources/aws_subnets.md.erb +126 -126
- data/docs/resources/aws_vpc.md.erb +120 -120
- data/docs/resources/aws_vpcs.md.erb +48 -48
- data/docs/resources/azure_generic_resource.md.erb +170 -170
- 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/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 +104 -104
- 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 -515
- 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 +196 -196
- 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_def.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 +128 -128
- 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 +78 -78
- 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 -144
- data/docs/resources/ssh_config.md.erb +80 -80
- 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 +215 -215
- 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 +22 -22
- 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 +53 -53
- data/inspec.gemspec +47 -47
- 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 +185 -185
- data/lib/bundles/inspec-compliance/api.rb +316 -316
- data/lib/bundles/inspec-compliance/api/login.rb +152 -152
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
- data/lib/bundles/inspec-compliance/cli.rb +254 -254
- data/lib/bundles/inspec-compliance/configuration.rb +103 -103
- data/lib/bundles/inspec-compliance/http.rb +86 -86
- data/lib/bundles/inspec-compliance/support.rb +36 -36
- data/lib/bundles/inspec-compliance/target.rb +98 -98
- 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 +390 -390
- 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 +204 -204
- 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 +92 -92
- data/lib/inspec/base_cli.rb +355 -350
- 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 +13 -13
- 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 +250 -250
- 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 +65 -65
- 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 +510 -510
- data/lib/inspec/profile_context.rb +207 -207
- data/lib/inspec/profile_vendor.rb +66 -66
- data/lib/inspec/reporters.rb +54 -50
- data/lib/inspec/reporters/base.rb +24 -24
- data/lib/inspec/reporters/cli.rb +356 -356
- data/lib/inspec/reporters/json.rb +116 -116
- data/lib/inspec/reporters/json_min.rb +48 -48
- data/lib/inspec/reporters/junit.rb +77 -77
- data/lib/inspec/require_loader.rb +33 -33
- data/lib/inspec/resource.rb +186 -186
- data/lib/inspec/rule.rb +266 -266
- 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 +41 -41
- 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 +159 -160
- data/lib/resources/apache.rb +48 -48
- data/lib/resources/apache_conf.rb +156 -156
- 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 +55 -55
- data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
- 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_recorder.rb +98 -98
- data/lib/resources/aws/aws_ec2_instance.rb +157 -157
- data/lib/resources/aws/aws_iam_access_key.rb +106 -106
- data/lib/resources/aws/aws_iam_access_keys.rb +149 -144
- data/lib/resources/aws/aws_iam_group.rb +56 -56
- data/lib/resources/aws/aws_iam_groups.rb +52 -45
- data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
- data/lib/resources/aws/aws_iam_policies.rb +53 -46
- data/lib/resources/aws/aws_iam_policy.rb +125 -119
- data/lib/resources/aws/aws_iam_role.rb +51 -51
- data/lib/resources/aws/aws_iam_root_user.rb +60 -60
- data/lib/resources/aws/aws_iam_user.rb +111 -111
- data/lib/resources/aws/aws_iam_users.rb +108 -96
- data/lib/resources/aws/aws_kms_keys.rb +53 -46
- data/lib/resources/aws/aws_route_table.rb +61 -61
- data/lib/resources/aws/aws_s3_bucket.rb +115 -115
- data/lib/resources/aws/aws_security_group.rb +93 -93
- data/lib/resources/aws/aws_security_groups.rb +68 -68
- data/lib/resources/aws/aws_sns_topic.rb +53 -53
- 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 +69 -69
- data/lib/resources/aws/aws_vpcs.rb +45 -45
- 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 +136 -136
- data/lib/resources/bash.rb +35 -35
- data/lib/resources/bond.rb +68 -68
- data/lib/resources/bridge.rb +122 -122
- data/lib/resources/command.rb +73 -69
- data/lib/resources/cpan.rb +58 -58
- data/lib/resources/cran.rb +64 -64
- data/lib/resources/crontab.rb +169 -170
- data/lib/resources/csv.rb +60 -60
- data/lib/resources/dh_params.rb +82 -82
- 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 +101 -102
- data/lib/resources/etc_group.rb +152 -156
- data/lib/resources/etc_hosts.rb +82 -81
- data/lib/resources/etc_hosts_allow_deny.rb +122 -123
- data/lib/resources/file.rb +298 -298
- data/lib/resources/filesystem.rb +31 -31
- data/lib/resources/firewalld.rb +143 -144
- data/lib/resources/gem.rb +70 -70
- data/lib/resources/groups.rb +215 -215
- data/lib/resources/grub_conf.rb +237 -237
- data/lib/resources/host.rb +306 -300
- data/lib/resources/http.rb +251 -250
- data/lib/resources/iis_app.rb +101 -104
- data/lib/resources/iis_site.rb +148 -148
- data/lib/resources/inetd_conf.rb +62 -62
- data/lib/resources/ini.rb +29 -29
- data/lib/resources/interface.rb +129 -129
- data/lib/resources/iptables.rb +80 -69
- data/lib/resources/json.rb +117 -117
- data/lib/resources/kernel_module.rb +107 -107
- data/lib/resources/kernel_parameter.rb +58 -58
- data/lib/resources/key_rsa.rb +67 -67
- data/lib/resources/limits_conf.rb +55 -55
- data/lib/resources/login_def.rb +66 -66
- data/lib/resources/mount.rb +88 -88
- data/lib/resources/mssql_session.rb +101 -101
- data/lib/resources/mysql.rb +81 -81
- data/lib/resources/mysql_conf.rb +134 -134
- data/lib/resources/mysql_session.rb +71 -71
- data/lib/resources/nginx.rb +96 -96
- data/lib/resources/nginx_conf.rb +227 -227
- data/lib/resources/npm.rb +48 -48
- data/lib/resources/ntp_conf.rb +58 -58
- 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 +76 -76
- data/lib/resources/package.rb +370 -370
- data/lib/resources/packages.rb +111 -111
- data/lib/resources/parse_config.rb +116 -116
- data/lib/resources/passwd.rb +74 -74
- data/lib/resources/pip.rb +89 -89
- data/lib/resources/platform.rb +109 -109
- data/lib/resources/port.rb +771 -771
- data/lib/resources/postgres.rb +130 -130
- data/lib/resources/postgres_conf.rb +121 -121
- data/lib/resources/postgres_hba_conf.rb +99 -100
- data/lib/resources/postgres_ident_conf.rb +76 -78
- data/lib/resources/postgres_session.rb +71 -71
- data/lib/resources/powershell.rb +53 -57
- data/lib/resources/processes.rb +204 -204
- data/lib/resources/rabbitmq_conf.rb +52 -52
- data/lib/resources/registry_key.rb +296 -296
- data/lib/resources/security_policy.rb +180 -180
- data/lib/resources/service.rb +789 -789
- data/lib/resources/shadow.rb +146 -140
- data/lib/resources/ssh_conf.rb +102 -102
- 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 -69
- 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 -105
- data/lib/resources/wmi.rb +110 -113
- data/lib/resources/x509_certificate.rb +143 -143
- data/lib/resources/xinetd.rb +111 -111
- data/lib/resources/xml.rb +46 -46
- data/lib/resources/yaml.rb +47 -47
- 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/erlang_parser.rb +192 -192
- data/lib/utils/filter.rb +272 -272
- data/lib/utils/filter_array.rb +27 -27
- data/lib/utils/find_files.rb +44 -44
- 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 +85 -85
- data/lib/utils/object_traversal.rb +49 -49
- data/lib/utils/parser.rb +274 -274
- 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 +2 -2
data/lib/inspec/errors.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# author: Dominik Richter
|
|
3
|
-
# author: Christoph Hartmann
|
|
4
|
-
|
|
5
|
-
module Inspec
|
|
6
|
-
class Error < StandardError; end
|
|
7
|
-
|
|
8
|
-
# dependency resolution
|
|
9
|
-
class CyclicDependencyError < Error; end
|
|
10
|
-
class UnsatisfiedVersionSpecification < Error; end
|
|
11
|
-
class DuplicateDep < Error; end
|
|
12
|
-
class FetcherFailure < Error; end
|
|
13
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Dominik Richter
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
|
|
5
|
+
module Inspec
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
|
|
8
|
+
# dependency resolution
|
|
9
|
+
class CyclicDependencyError < Error; end
|
|
10
|
+
class UnsatisfiedVersionSpecification < Error; end
|
|
11
|
+
class DuplicateDep < Error; end
|
|
12
|
+
class FetcherFailure < Error; end
|
|
13
|
+
end
|
data/lib/inspec/exceptions.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# copyright: 2017, Chef Software Inc.
|
|
3
|
-
|
|
4
|
-
module Inspec
|
|
5
|
-
module Exceptions
|
|
6
|
-
class AttributesFileDoesNotExist < ArgumentError; end
|
|
7
|
-
class AttributesFileNotReadable < ArgumentError; end
|
|
8
|
-
class ResourceFailed < StandardError; end
|
|
9
|
-
class ResourceSkipped < StandardError; end
|
|
10
|
-
class SecretsBackendNotFound < ArgumentError; end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2017, Chef Software Inc.
|
|
3
|
+
|
|
4
|
+
module Inspec
|
|
5
|
+
module Exceptions
|
|
6
|
+
class AttributesFileDoesNotExist < ArgumentError; end
|
|
7
|
+
class AttributesFileNotReadable < ArgumentError; end
|
|
8
|
+
class ResourceFailed < StandardError; end
|
|
9
|
+
class ResourceSkipped < StandardError; end
|
|
10
|
+
class SecretsBackendNotFound < ArgumentError; end
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/inspec/expect.rb
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# copyright: 2016, Chef Software Inc.
|
|
3
|
-
# author: Dominik Richter
|
|
4
|
-
# author: Christoph Hartmann
|
|
5
|
-
|
|
6
|
-
require 'rspec/expectations'
|
|
7
|
-
|
|
8
|
-
module Inspec
|
|
9
|
-
class Expect
|
|
10
|
-
attr_reader :calls, :value, :block
|
|
11
|
-
def initialize(value, &block)
|
|
12
|
-
@value = value
|
|
13
|
-
@block = block
|
|
14
|
-
@calls = []
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def to(*args, &block)
|
|
18
|
-
@calls.push([:to, args, block, caller])
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def not_to(*args, &block)
|
|
22
|
-
@calls.push([:not_to, args, block, caller])
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def example_group
|
|
26
|
-
that = self
|
|
27
|
-
|
|
28
|
-
opts = { 'caller' => calls[0][3] }
|
|
29
|
-
if !calls[0][3].nil? && !calls[0][3].empty? &&
|
|
30
|
-
(m = calls[0][3][0].match(/^([^:]*):(\d+):/))
|
|
31
|
-
opts['file_path'] = m[0]
|
|
32
|
-
opts['line_number'] = m[1]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
RSpec::Core::ExampleGroup.describe(that.value, opts) do
|
|
36
|
-
that.calls.each do |method, args, block, clr|
|
|
37
|
-
it(nil, caller: clr) do
|
|
38
|
-
x = expect(that.value, &that.block).method(method)
|
|
39
|
-
x.call(*args, &block)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2016, Chef Software Inc.
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
# author: Christoph Hartmann
|
|
5
|
+
|
|
6
|
+
require 'rspec/expectations'
|
|
7
|
+
|
|
8
|
+
module Inspec
|
|
9
|
+
class Expect
|
|
10
|
+
attr_reader :calls, :value, :block
|
|
11
|
+
def initialize(value, &block)
|
|
12
|
+
@value = value
|
|
13
|
+
@block = block
|
|
14
|
+
@calls = []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to(*args, &block)
|
|
18
|
+
@calls.push([:to, args, block, caller])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def not_to(*args, &block)
|
|
22
|
+
@calls.push([:not_to, args, block, caller])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def example_group
|
|
26
|
+
that = self
|
|
27
|
+
|
|
28
|
+
opts = { 'caller' => calls[0][3] }
|
|
29
|
+
if !calls[0][3].nil? && !calls[0][3].empty? &&
|
|
30
|
+
(m = calls[0][3][0].match(/^([^:]*):(\d+):/))
|
|
31
|
+
opts['file_path'] = m[0]
|
|
32
|
+
opts['line_number'] = m[1]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
RSpec::Core::ExampleGroup.describe(that.value, opts) do
|
|
36
|
+
that.calls.each do |method, args, block, clr|
|
|
37
|
+
it(nil, caller: clr) do
|
|
38
|
+
x = expect(that.value, &that.block).method(method)
|
|
39
|
+
x.call(*args, &block)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/inspec/fetcher.rb
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# author: Dominik Richter
|
|
3
|
-
# author: Christoph Hartmann
|
|
4
|
-
|
|
5
|
-
require 'inspec/plugins'
|
|
6
|
-
require 'utils/plugin_registry'
|
|
7
|
-
|
|
8
|
-
module Inspec
|
|
9
|
-
class FetcherRegistry < PluginRegistry
|
|
10
|
-
def resolve(target)
|
|
11
|
-
if fetcher_specified?(target)
|
|
12
|
-
super(target)
|
|
13
|
-
else
|
|
14
|
-
Inspec::Log.debug("Assuming default supermarket source for #{target}")
|
|
15
|
-
super(with_default_fetcher(target))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
|
|
20
|
-
def fetcher_specified?(target)
|
|
21
|
-
# Only set a default for Hash-based (i.e. from
|
|
22
|
-
# inspec.yml/inspec.lock) targets
|
|
23
|
-
|
|
24
|
-
return true if !target.respond_to?(:keys)
|
|
25
|
-
!(target.keys - NON_FETCHER_KEYS).empty?
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def with_default_fetcher(target)
|
|
29
|
-
target.merge({ supermarket: target[:name] })
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
Fetcher = FetcherRegistry.new
|
|
34
|
-
|
|
35
|
-
def self.fetcher(version)
|
|
36
|
-
if version != 1
|
|
37
|
-
raise 'Only fetcher version 1 is supported!'
|
|
38
|
-
end
|
|
39
|
-
Inspec::Plugins::Fetcher
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
require 'fetchers/local'
|
|
44
|
-
require 'fetchers/url'
|
|
45
|
-
require 'fetchers/git'
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Dominik Richter
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
|
|
5
|
+
require 'inspec/plugins'
|
|
6
|
+
require 'utils/plugin_registry'
|
|
7
|
+
|
|
8
|
+
module Inspec
|
|
9
|
+
class FetcherRegistry < PluginRegistry
|
|
10
|
+
def resolve(target)
|
|
11
|
+
if fetcher_specified?(target)
|
|
12
|
+
super(target)
|
|
13
|
+
else
|
|
14
|
+
Inspec::Log.debug("Assuming default supermarket source for #{target}")
|
|
15
|
+
super(with_default_fetcher(target))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
|
|
20
|
+
def fetcher_specified?(target)
|
|
21
|
+
# Only set a default for Hash-based (i.e. from
|
|
22
|
+
# inspec.yml/inspec.lock) targets
|
|
23
|
+
|
|
24
|
+
return true if !target.respond_to?(:keys)
|
|
25
|
+
!(target.keys - NON_FETCHER_KEYS).empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def with_default_fetcher(target)
|
|
29
|
+
target.merge({ supermarket: target[:name] })
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Fetcher = FetcherRegistry.new
|
|
34
|
+
|
|
35
|
+
def self.fetcher(version)
|
|
36
|
+
if version != 1
|
|
37
|
+
raise 'Only fetcher version 1 is supported!'
|
|
38
|
+
end
|
|
39
|
+
Inspec::Plugins::Fetcher
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
require 'fetchers/local'
|
|
44
|
+
require 'fetchers/url'
|
|
45
|
+
require 'fetchers/git'
|
data/lib/inspec/file_provider.rb
CHANGED
|
@@ -1,275 +1,275 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
require 'rubygems/package'
|
|
3
|
-
require 'zlib'
|
|
4
|
-
require 'zip'
|
|
5
|
-
|
|
6
|
-
module Inspec
|
|
7
|
-
class FileProvider
|
|
8
|
-
def self.for_path(path)
|
|
9
|
-
if path.is_a?(Hash)
|
|
10
|
-
MockProvider.new(path)
|
|
11
|
-
elsif File.directory?(path)
|
|
12
|
-
DirProvider.new(path)
|
|
13
|
-
elsif File.exist?(path) && path.end_with?('.tar.gz', 'tgz')
|
|
14
|
-
TarProvider.new(path)
|
|
15
|
-
elsif File.exist?(path) && path.end_with?('.zip')
|
|
16
|
-
ZipProvider.new(path)
|
|
17
|
-
elsif File.exist?(path)
|
|
18
|
-
DirProvider.new(path)
|
|
19
|
-
else
|
|
20
|
-
raise "No file provider for the provided path: #{path}"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def initialize(_path)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# List all files that are offered.
|
|
28
|
-
#
|
|
29
|
-
# @return [Array[String]] list of file paths that are included
|
|
30
|
-
def files
|
|
31
|
-
raise "Fetcher #{self} does not implement `files()`. This is required."
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Read the contents of a file. This will typically refer to a text
|
|
35
|
-
# file reading a string.
|
|
36
|
-
#
|
|
37
|
-
# @param _file [String] path of the file to be read
|
|
38
|
-
# @return [String] contents of the file described
|
|
39
|
-
def read(_file)
|
|
40
|
-
raise "#{self} does not implement `read(...)`. This is required."
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Provide a method for reading binary contents from a file.
|
|
44
|
-
# It will default to #read if not defined. For most streams that implement
|
|
45
|
-
# it, it will be the same. For some special cases, it will add change the
|
|
46
|
-
# way in which encoding of the returned data structure is handled.
|
|
47
|
-
# Does not work with alias nor alias_method.
|
|
48
|
-
def binread(file)
|
|
49
|
-
read(file)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def relative_provider
|
|
53
|
-
RelativeFileProvider.new(self)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
class MockProvider < FileProvider
|
|
58
|
-
attr_reader :files
|
|
59
|
-
def initialize(path)
|
|
60
|
-
@data = path[:mock]
|
|
61
|
-
@files = @data.keys
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def read(file)
|
|
65
|
-
@data[file]
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
class DirProvider < FileProvider
|
|
70
|
-
attr_reader :files
|
|
71
|
-
def initialize(path)
|
|
72
|
-
@files = if File.file?(path)
|
|
73
|
-
[path]
|
|
74
|
-
else
|
|
75
|
-
Dir[File.join(Shellwords.shellescape(path), '**', '*')]
|
|
76
|
-
end
|
|
77
|
-
@path = path
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def read(file)
|
|
81
|
-
return nil unless files.include?(file)
|
|
82
|
-
return nil unless File.file?(file)
|
|
83
|
-
File.read(file)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def binread(file)
|
|
87
|
-
return nil unless files.include?(file)
|
|
88
|
-
return nil unless File.file?(file)
|
|
89
|
-
File.binread(file)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
class ZipProvider < FileProvider
|
|
94
|
-
attr_reader :files
|
|
95
|
-
|
|
96
|
-
def initialize(path)
|
|
97
|
-
@path = path
|
|
98
|
-
@contents = {}
|
|
99
|
-
@files = []
|
|
100
|
-
walk_zip(@path) do |io|
|
|
101
|
-
while (entry = io.get_next_entry)
|
|
102
|
-
name = entry.name.sub(%r{/+$}, '')
|
|
103
|
-
@files.push(name) unless name.empty?
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def read(file)
|
|
109
|
-
@contents[file] ||= read_from_zip(file)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
private
|
|
113
|
-
|
|
114
|
-
def walk_zip(path, &callback)
|
|
115
|
-
::Zip::InputStream.open(path, &callback)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def read_from_zip(file)
|
|
119
|
-
return nil unless @files.include?(file)
|
|
120
|
-
res = nil
|
|
121
|
-
walk_zip(@path) do |io|
|
|
122
|
-
while (entry = io.get_next_entry)
|
|
123
|
-
next unless file == entry.name
|
|
124
|
-
res = io.read
|
|
125
|
-
break
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
res
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
class TarProvider < FileProvider
|
|
133
|
-
attr_reader :files
|
|
134
|
-
|
|
135
|
-
def initialize(path)
|
|
136
|
-
@path = path
|
|
137
|
-
@contents = {}
|
|
138
|
-
@files = []
|
|
139
|
-
walk_tar(@path) do |tar|
|
|
140
|
-
@files = tar.find_all(&:file?)
|
|
141
|
-
|
|
142
|
-
# delete all entries with no name
|
|
143
|
-
@files = @files.find_all { |x| !x.full_name.empty? }
|
|
144
|
-
|
|
145
|
-
# delete all entries that have a PaxHeader
|
|
146
|
-
@files = @files.delete_if { |x| x.full_name.include?('PaxHeader/') }
|
|
147
|
-
|
|
148
|
-
# replace all items of the array simply with the relative filename of the file
|
|
149
|
-
@files.map! { |x| Pathname.new(x.full_name).relative_path_from(Pathname.new('.')).to_s }
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def read(file)
|
|
154
|
-
@contents[file] ||= read_from_tar(file)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
private
|
|
158
|
-
|
|
159
|
-
def walk_tar(path, &callback)
|
|
160
|
-
Gem::Package::TarReader.new(Zlib::GzipReader.open(path), &callback)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def read_from_tar(file)
|
|
164
|
-
return nil unless @files.include?(file)
|
|
165
|
-
res = nil
|
|
166
|
-
# NB `TarReader` includes `Enumerable` beginning with Ruby 2.x
|
|
167
|
-
walk_tar(@path) do |tar|
|
|
168
|
-
tar.each do |entry|
|
|
169
|
-
next unless entry.file? && [file, "./#{file}"].include?(entry.full_name)
|
|
170
|
-
res = entry.read
|
|
171
|
-
break
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
res
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
class RelativeFileProvider
|
|
179
|
-
BLACKLIST_FILES = [
|
|
180
|
-
'/pax_global_header',
|
|
181
|
-
'pax_global_header',
|
|
182
|
-
].freeze
|
|
183
|
-
|
|
184
|
-
attr_reader :files
|
|
185
|
-
attr_reader :prefix
|
|
186
|
-
attr_reader :parent
|
|
187
|
-
|
|
188
|
-
def initialize(parent_provider)
|
|
189
|
-
@parent = parent_provider
|
|
190
|
-
@prefix = get_prefix(parent.files)
|
|
191
|
-
if @prefix.nil?
|
|
192
|
-
raise "Could not determine path prefix for #{parent}"
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# select all files that begin with the prefix, and strip off the prefix from the file.
|
|
196
|
-
#
|
|
197
|
-
# strip off any leading top-level relative path (./) which is common in
|
|
198
|
-
# PAX-formatted tar files. Do not do any translation of the path if the
|
|
199
|
-
# path is an absolute path.
|
|
200
|
-
@files = parent.files
|
|
201
|
-
.find_all { |x| x.start_with?(prefix) && x != prefix }
|
|
202
|
-
.map { |x| x[prefix.length..-1] }
|
|
203
|
-
.map do |x|
|
|
204
|
-
path = Pathname.new(x)
|
|
205
|
-
path.absolute? ? path.to_s : path.relative_path_from(Pathname.new('.')).to_s
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def abs_path(file)
|
|
210
|
-
return nil if file.nil?
|
|
211
|
-
prefix + file
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def read(file)
|
|
215
|
-
parent.read(abs_path(file))
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def binread(file)
|
|
219
|
-
parent.binread(abs_path(file))
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
private
|
|
223
|
-
|
|
224
|
-
def get_prefix(fs)
|
|
225
|
-
return '' if fs.empty?
|
|
226
|
-
|
|
227
|
-
# filter backlisted files
|
|
228
|
-
fs -= BLACKLIST_FILES
|
|
229
|
-
|
|
230
|
-
sorted = fs.sort_by(&:length)
|
|
231
|
-
get_folder_prefix(sorted)
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def prefix_candidate_for(file)
|
|
235
|
-
if file.end_with?(File::SEPARATOR)
|
|
236
|
-
file
|
|
237
|
-
else
|
|
238
|
-
file + File::SEPARATOR
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def get_folder_prefix(fs)
|
|
243
|
-
return get_files_prefix(fs) if fs.length == 1
|
|
244
|
-
first, *rest = fs
|
|
245
|
-
pre = prefix_candidate_for(first)
|
|
246
|
-
|
|
247
|
-
if rest.all? { |i| i.start_with? pre }
|
|
248
|
-
return get_folder_prefix(rest)
|
|
249
|
-
end
|
|
250
|
-
get_files_prefix(fs)
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def get_files_prefix(fs)
|
|
254
|
-
return '' if fs.empty?
|
|
255
|
-
|
|
256
|
-
file = fs[0]
|
|
257
|
-
bn = File.basename(file)
|
|
258
|
-
# no more prefixes
|
|
259
|
-
return '' if bn == file
|
|
260
|
-
|
|
261
|
-
i = file.rindex(bn)
|
|
262
|
-
pre = file[0..i-1]
|
|
263
|
-
|
|
264
|
-
rest = fs.find_all { |f| !f.start_with?(pre) }
|
|
265
|
-
return pre if rest.empty?
|
|
266
|
-
|
|
267
|
-
new_pre = get_prefix(rest)
|
|
268
|
-
return new_pre if pre.start_with? new_pre
|
|
269
|
-
# edge case: completely different prefixes; retry prefix detection
|
|
270
|
-
a = File.dirname(pre + 'a')
|
|
271
|
-
b = File.dirname(new_pre + 'b')
|
|
272
|
-
get_prefix([a, b])
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'rubygems/package'
|
|
3
|
+
require 'zlib'
|
|
4
|
+
require 'zip'
|
|
5
|
+
|
|
6
|
+
module Inspec
|
|
7
|
+
class FileProvider
|
|
8
|
+
def self.for_path(path)
|
|
9
|
+
if path.is_a?(Hash)
|
|
10
|
+
MockProvider.new(path)
|
|
11
|
+
elsif File.directory?(path)
|
|
12
|
+
DirProvider.new(path)
|
|
13
|
+
elsif File.exist?(path) && path.end_with?('.tar.gz', 'tgz')
|
|
14
|
+
TarProvider.new(path)
|
|
15
|
+
elsif File.exist?(path) && path.end_with?('.zip')
|
|
16
|
+
ZipProvider.new(path)
|
|
17
|
+
elsif File.exist?(path)
|
|
18
|
+
DirProvider.new(path)
|
|
19
|
+
else
|
|
20
|
+
raise "No file provider for the provided path: #{path}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(_path)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# List all files that are offered.
|
|
28
|
+
#
|
|
29
|
+
# @return [Array[String]] list of file paths that are included
|
|
30
|
+
def files
|
|
31
|
+
raise "Fetcher #{self} does not implement `files()`. This is required."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Read the contents of a file. This will typically refer to a text
|
|
35
|
+
# file reading a string.
|
|
36
|
+
#
|
|
37
|
+
# @param _file [String] path of the file to be read
|
|
38
|
+
# @return [String] contents of the file described
|
|
39
|
+
def read(_file)
|
|
40
|
+
raise "#{self} does not implement `read(...)`. This is required."
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Provide a method for reading binary contents from a file.
|
|
44
|
+
# It will default to #read if not defined. For most streams that implement
|
|
45
|
+
# it, it will be the same. For some special cases, it will add change the
|
|
46
|
+
# way in which encoding of the returned data structure is handled.
|
|
47
|
+
# Does not work with alias nor alias_method.
|
|
48
|
+
def binread(file)
|
|
49
|
+
read(file)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def relative_provider
|
|
53
|
+
RelativeFileProvider.new(self)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class MockProvider < FileProvider
|
|
58
|
+
attr_reader :files
|
|
59
|
+
def initialize(path)
|
|
60
|
+
@data = path[:mock]
|
|
61
|
+
@files = @data.keys
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def read(file)
|
|
65
|
+
@data[file]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class DirProvider < FileProvider
|
|
70
|
+
attr_reader :files
|
|
71
|
+
def initialize(path)
|
|
72
|
+
@files = if File.file?(path)
|
|
73
|
+
[path]
|
|
74
|
+
else
|
|
75
|
+
Dir[File.join(Shellwords.shellescape(path), '**', '*')]
|
|
76
|
+
end
|
|
77
|
+
@path = path
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def read(file)
|
|
81
|
+
return nil unless files.include?(file)
|
|
82
|
+
return nil unless File.file?(file)
|
|
83
|
+
File.read(file)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def binread(file)
|
|
87
|
+
return nil unless files.include?(file)
|
|
88
|
+
return nil unless File.file?(file)
|
|
89
|
+
File.binread(file)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
class ZipProvider < FileProvider
|
|
94
|
+
attr_reader :files
|
|
95
|
+
|
|
96
|
+
def initialize(path)
|
|
97
|
+
@path = path
|
|
98
|
+
@contents = {}
|
|
99
|
+
@files = []
|
|
100
|
+
walk_zip(@path) do |io|
|
|
101
|
+
while (entry = io.get_next_entry)
|
|
102
|
+
name = entry.name.sub(%r{/+$}, '')
|
|
103
|
+
@files.push(name) unless name.empty?
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def read(file)
|
|
109
|
+
@contents[file] ||= read_from_zip(file)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
def walk_zip(path, &callback)
|
|
115
|
+
::Zip::InputStream.open(path, &callback)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def read_from_zip(file)
|
|
119
|
+
return nil unless @files.include?(file)
|
|
120
|
+
res = nil
|
|
121
|
+
walk_zip(@path) do |io|
|
|
122
|
+
while (entry = io.get_next_entry)
|
|
123
|
+
next unless file == entry.name
|
|
124
|
+
res = io.read
|
|
125
|
+
break
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
res
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
class TarProvider < FileProvider
|
|
133
|
+
attr_reader :files
|
|
134
|
+
|
|
135
|
+
def initialize(path)
|
|
136
|
+
@path = path
|
|
137
|
+
@contents = {}
|
|
138
|
+
@files = []
|
|
139
|
+
walk_tar(@path) do |tar|
|
|
140
|
+
@files = tar.find_all(&:file?)
|
|
141
|
+
|
|
142
|
+
# delete all entries with no name
|
|
143
|
+
@files = @files.find_all { |x| !x.full_name.empty? }
|
|
144
|
+
|
|
145
|
+
# delete all entries that have a PaxHeader
|
|
146
|
+
@files = @files.delete_if { |x| x.full_name.include?('PaxHeader/') }
|
|
147
|
+
|
|
148
|
+
# replace all items of the array simply with the relative filename of the file
|
|
149
|
+
@files.map! { |x| Pathname.new(x.full_name).relative_path_from(Pathname.new('.')).to_s }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def read(file)
|
|
154
|
+
@contents[file] ||= read_from_tar(file)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
def walk_tar(path, &callback)
|
|
160
|
+
Gem::Package::TarReader.new(Zlib::GzipReader.open(path), &callback)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def read_from_tar(file)
|
|
164
|
+
return nil unless @files.include?(file)
|
|
165
|
+
res = nil
|
|
166
|
+
# NB `TarReader` includes `Enumerable` beginning with Ruby 2.x
|
|
167
|
+
walk_tar(@path) do |tar|
|
|
168
|
+
tar.each do |entry|
|
|
169
|
+
next unless entry.file? && [file, "./#{file}"].include?(entry.full_name)
|
|
170
|
+
res = entry.read
|
|
171
|
+
break
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
res
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
class RelativeFileProvider
|
|
179
|
+
BLACKLIST_FILES = [
|
|
180
|
+
'/pax_global_header',
|
|
181
|
+
'pax_global_header',
|
|
182
|
+
].freeze
|
|
183
|
+
|
|
184
|
+
attr_reader :files
|
|
185
|
+
attr_reader :prefix
|
|
186
|
+
attr_reader :parent
|
|
187
|
+
|
|
188
|
+
def initialize(parent_provider)
|
|
189
|
+
@parent = parent_provider
|
|
190
|
+
@prefix = get_prefix(parent.files)
|
|
191
|
+
if @prefix.nil?
|
|
192
|
+
raise "Could not determine path prefix for #{parent}"
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# select all files that begin with the prefix, and strip off the prefix from the file.
|
|
196
|
+
#
|
|
197
|
+
# strip off any leading top-level relative path (./) which is common in
|
|
198
|
+
# PAX-formatted tar files. Do not do any translation of the path if the
|
|
199
|
+
# path is an absolute path.
|
|
200
|
+
@files = parent.files
|
|
201
|
+
.find_all { |x| x.start_with?(prefix) && x != prefix }
|
|
202
|
+
.map { |x| x[prefix.length..-1] }
|
|
203
|
+
.map do |x|
|
|
204
|
+
path = Pathname.new(x)
|
|
205
|
+
path.absolute? ? path.to_s : path.relative_path_from(Pathname.new('.')).to_s
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def abs_path(file)
|
|
210
|
+
return nil if file.nil?
|
|
211
|
+
prefix + file
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def read(file)
|
|
215
|
+
parent.read(abs_path(file))
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def binread(file)
|
|
219
|
+
parent.binread(abs_path(file))
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
private
|
|
223
|
+
|
|
224
|
+
def get_prefix(fs)
|
|
225
|
+
return '' if fs.empty?
|
|
226
|
+
|
|
227
|
+
# filter backlisted files
|
|
228
|
+
fs -= BLACKLIST_FILES
|
|
229
|
+
|
|
230
|
+
sorted = fs.sort_by(&:length)
|
|
231
|
+
get_folder_prefix(sorted)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def prefix_candidate_for(file)
|
|
235
|
+
if file.end_with?(File::SEPARATOR)
|
|
236
|
+
file
|
|
237
|
+
else
|
|
238
|
+
file + File::SEPARATOR
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def get_folder_prefix(fs)
|
|
243
|
+
return get_files_prefix(fs) if fs.length == 1
|
|
244
|
+
first, *rest = fs
|
|
245
|
+
pre = prefix_candidate_for(first)
|
|
246
|
+
|
|
247
|
+
if rest.all? { |i| i.start_with? pre }
|
|
248
|
+
return get_folder_prefix(rest)
|
|
249
|
+
end
|
|
250
|
+
get_files_prefix(fs)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def get_files_prefix(fs)
|
|
254
|
+
return '' if fs.empty?
|
|
255
|
+
|
|
256
|
+
file = fs[0]
|
|
257
|
+
bn = File.basename(file)
|
|
258
|
+
# no more prefixes
|
|
259
|
+
return '' if bn == file
|
|
260
|
+
|
|
261
|
+
i = file.rindex(bn)
|
|
262
|
+
pre = file[0..i-1]
|
|
263
|
+
|
|
264
|
+
rest = fs.find_all { |f| !f.start_with?(pre) }
|
|
265
|
+
return pre if rest.empty?
|
|
266
|
+
|
|
267
|
+
new_pre = get_prefix(rest)
|
|
268
|
+
return new_pre if pre.start_with? new_pre
|
|
269
|
+
# edge case: completely different prefixes; retry prefix detection
|
|
270
|
+
a = File.dirname(pre + 'a')
|
|
271
|
+
b = File.dirname(new_pre + 'b')
|
|
272
|
+
get_prefix([a, b])
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|