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/resources/csv.rb
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
# Parses a csv document
|
|
4
|
-
# This implementation was inspired by a blog post
|
|
5
|
-
# @see http://technicalpickles.com/posts/parsing-csv-with-ruby
|
|
6
|
-
module Inspec::Resources
|
|
7
|
-
class CsvConfig < JsonConfig
|
|
8
|
-
name 'csv'
|
|
9
|
-
supports platform: 'unix'
|
|
10
|
-
supports platform: 'windows'
|
|
11
|
-
supports platform: 'esx'
|
|
12
|
-
supports platform: 'cisco'
|
|
13
|
-
desc 'Use the csv InSpec audit resource to test configuration data in a CSV file.'
|
|
14
|
-
example "
|
|
15
|
-
describe csv('example.csv') do
|
|
16
|
-
its('name') { should eq(['John', 'Alice']) }
|
|
17
|
-
end
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
# override the parse method from JsonConfig
|
|
21
|
-
# Assuming a header row of name,col1,col2, it will output an array of hashes like so:
|
|
22
|
-
# [
|
|
23
|
-
# { 'name' => 'row1', 'col1' => 'value1', 'col2' => 'value2' },
|
|
24
|
-
# { 'name' => 'row2', 'col1' => 'value3', 'col2' => 'value4' }
|
|
25
|
-
# ]
|
|
26
|
-
def parse(content)
|
|
27
|
-
require 'csv'
|
|
28
|
-
|
|
29
|
-
# convert empty field to nil
|
|
30
|
-
CSV::Converters[:blank_to_nil] = lambda do |field|
|
|
31
|
-
field && field.empty? ? nil : field
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# implicit conversion of values
|
|
35
|
-
csv = CSV.new(content, headers: true, converters: [:all, :blank_to_nil])
|
|
36
|
-
|
|
37
|
-
# convert to hash
|
|
38
|
-
csv.to_a.map(&:to_hash)
|
|
39
|
-
rescue => e
|
|
40
|
-
raise Inspec::Exceptions::ResourceFailed, "Unable to parse CSV: #{e.message}"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# override the value method from JsonConfig
|
|
44
|
-
# The format of the CSV hash as created by #parse is very different
|
|
45
|
-
# than what the YAML, JSON, and INI resources create, so using the
|
|
46
|
-
# #value method from JsonConfig (which uses ObjectTraverser.extract_value)
|
|
47
|
-
# doesn't make sense here.
|
|
48
|
-
def value(key)
|
|
49
|
-
@params.map { |x| x[key.first.to_s] }.compact
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
# used by JsonConfig to build up a full to_s method
|
|
55
|
-
# based on whether a file path, content, or command was supplied.
|
|
56
|
-
def resource_base_name
|
|
57
|
-
'CSV'
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
# Parses a csv document
|
|
4
|
+
# This implementation was inspired by a blog post
|
|
5
|
+
# @see http://technicalpickles.com/posts/parsing-csv-with-ruby
|
|
6
|
+
module Inspec::Resources
|
|
7
|
+
class CsvConfig < JsonConfig
|
|
8
|
+
name 'csv'
|
|
9
|
+
supports platform: 'unix'
|
|
10
|
+
supports platform: 'windows'
|
|
11
|
+
supports platform: 'esx'
|
|
12
|
+
supports platform: 'cisco'
|
|
13
|
+
desc 'Use the csv InSpec audit resource to test configuration data in a CSV file.'
|
|
14
|
+
example "
|
|
15
|
+
describe csv('example.csv') do
|
|
16
|
+
its('name') { should eq(['John', 'Alice']) }
|
|
17
|
+
end
|
|
18
|
+
"
|
|
19
|
+
|
|
20
|
+
# override the parse method from JsonConfig
|
|
21
|
+
# Assuming a header row of name,col1,col2, it will output an array of hashes like so:
|
|
22
|
+
# [
|
|
23
|
+
# { 'name' => 'row1', 'col1' => 'value1', 'col2' => 'value2' },
|
|
24
|
+
# { 'name' => 'row2', 'col1' => 'value3', 'col2' => 'value4' }
|
|
25
|
+
# ]
|
|
26
|
+
def parse(content)
|
|
27
|
+
require 'csv'
|
|
28
|
+
|
|
29
|
+
# convert empty field to nil
|
|
30
|
+
CSV::Converters[:blank_to_nil] = lambda do |field|
|
|
31
|
+
field && field.empty? ? nil : field
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# implicit conversion of values
|
|
35
|
+
csv = CSV.new(content, headers: true, converters: [:all, :blank_to_nil])
|
|
36
|
+
|
|
37
|
+
# convert to hash
|
|
38
|
+
csv.to_a.map(&:to_hash)
|
|
39
|
+
rescue => e
|
|
40
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to parse CSV: #{e.message}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# override the value method from JsonConfig
|
|
44
|
+
# The format of the CSV hash as created by #parse is very different
|
|
45
|
+
# than what the YAML, JSON, and INI resources create, so using the
|
|
46
|
+
# #value method from JsonConfig (which uses ObjectTraverser.extract_value)
|
|
47
|
+
# doesn't make sense here.
|
|
48
|
+
def value(key)
|
|
49
|
+
@params.map { |x| x[key.first.to_s] }.compact
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# used by JsonConfig to build up a full to_s method
|
|
55
|
+
# based on whether a file path, content, or command was supplied.
|
|
56
|
+
def resource_base_name
|
|
57
|
+
'CSV'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/resources/dh_params.rb
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'openssl'
|
|
4
|
-
|
|
5
|
-
class DhParams < Inspec.resource(1)
|
|
6
|
-
name 'dh_params'
|
|
7
|
-
supports platform: 'unix'
|
|
8
|
-
desc '
|
|
9
|
-
Use the `dh_params` InSpec audit resource to test Diffie-Hellman (DH)
|
|
10
|
-
parameters.
|
|
11
|
-
'
|
|
12
|
-
|
|
13
|
-
example "
|
|
14
|
-
describe dh_params('/path/to/file.dh_pem') do
|
|
15
|
-
it { should be_dh_params }
|
|
16
|
-
it { should be_valid }
|
|
17
|
-
its('generator') { should eq 2 }
|
|
18
|
-
its('modulus') { should eq '00:91:a0:15:89:e5:bc:38:93:12:02:fc:...' }
|
|
19
|
-
its('prime_length') { should eq 2048 }
|
|
20
|
-
its('pem') { should eq '-----BEGIN DH PARAMETERS...' }
|
|
21
|
-
its('text') { should eq 'PKCS#3 DH Parameters: (2048 bit)...' }
|
|
22
|
-
end
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
def initialize(filename)
|
|
26
|
-
@dh_params_path = filename
|
|
27
|
-
file = inspec.file(@dh_params_path)
|
|
28
|
-
return skip_resource "Unable to find DH parameters file #{@dh_params_path}" unless file.exist?
|
|
29
|
-
|
|
30
|
-
begin
|
|
31
|
-
@dh_params = OpenSSL::PKey::DH.new file.content
|
|
32
|
-
rescue
|
|
33
|
-
@dh_params = nil
|
|
34
|
-
return skip_resource "Unable to load DH parameters #{@dh_params_path}"
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# it { should be_dh_params }
|
|
39
|
-
def dh_params?
|
|
40
|
-
!@dh_params.nil?
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# its('generator') { should eq 2 }
|
|
44
|
-
def generator
|
|
45
|
-
return if @dh_params.nil?
|
|
46
|
-
@dh_params.g.to_i
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# its('modulus') { should eq '00:91:a0:15:89:e5:bc:38:93:12:02:fc:...' }
|
|
50
|
-
def modulus
|
|
51
|
-
return if @dh_params.nil?
|
|
52
|
-
'00:' + @dh_params.p.to_s(16).downcase.scan(/.{2}/).join(':')
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# its('pem') { should eq '-----BEGIN DH PARAMETERS...' }
|
|
56
|
-
def pem
|
|
57
|
-
return if @dh_params.nil?
|
|
58
|
-
@dh_params.to_pem
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# its('prime_length') { should be 2048 }
|
|
62
|
-
def prime_length
|
|
63
|
-
return if @dh_params.nil?
|
|
64
|
-
@dh_params.p.num_bits
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# its('text') { should eq 'human-readable-text' }
|
|
68
|
-
def text
|
|
69
|
-
return if @dh_params.nil?
|
|
70
|
-
@dh_params.to_text
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# it { should be_valid }
|
|
74
|
-
def valid?
|
|
75
|
-
return if @dh_params.nil?
|
|
76
|
-
@dh_params.params_ok?
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def to_s
|
|
80
|
-
"dh_params #{@dh_params_path}"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
|
|
5
|
+
class DhParams < Inspec.resource(1)
|
|
6
|
+
name 'dh_params'
|
|
7
|
+
supports platform: 'unix'
|
|
8
|
+
desc '
|
|
9
|
+
Use the `dh_params` InSpec audit resource to test Diffie-Hellman (DH)
|
|
10
|
+
parameters.
|
|
11
|
+
'
|
|
12
|
+
|
|
13
|
+
example "
|
|
14
|
+
describe dh_params('/path/to/file.dh_pem') do
|
|
15
|
+
it { should be_dh_params }
|
|
16
|
+
it { should be_valid }
|
|
17
|
+
its('generator') { should eq 2 }
|
|
18
|
+
its('modulus') { should eq '00:91:a0:15:89:e5:bc:38:93:12:02:fc:...' }
|
|
19
|
+
its('prime_length') { should eq 2048 }
|
|
20
|
+
its('pem') { should eq '-----BEGIN DH PARAMETERS...' }
|
|
21
|
+
its('text') { should eq 'PKCS#3 DH Parameters: (2048 bit)...' }
|
|
22
|
+
end
|
|
23
|
+
"
|
|
24
|
+
|
|
25
|
+
def initialize(filename)
|
|
26
|
+
@dh_params_path = filename
|
|
27
|
+
file = inspec.file(@dh_params_path)
|
|
28
|
+
return skip_resource "Unable to find DH parameters file #{@dh_params_path}" unless file.exist?
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
@dh_params = OpenSSL::PKey::DH.new file.content
|
|
32
|
+
rescue
|
|
33
|
+
@dh_params = nil
|
|
34
|
+
return skip_resource "Unable to load DH parameters #{@dh_params_path}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# it { should be_dh_params }
|
|
39
|
+
def dh_params?
|
|
40
|
+
!@dh_params.nil?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# its('generator') { should eq 2 }
|
|
44
|
+
def generator
|
|
45
|
+
return if @dh_params.nil?
|
|
46
|
+
@dh_params.g.to_i
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# its('modulus') { should eq '00:91:a0:15:89:e5:bc:38:93:12:02:fc:...' }
|
|
50
|
+
def modulus
|
|
51
|
+
return if @dh_params.nil?
|
|
52
|
+
'00:' + @dh_params.p.to_s(16).downcase.scan(/.{2}/).join(':')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# its('pem') { should eq '-----BEGIN DH PARAMETERS...' }
|
|
56
|
+
def pem
|
|
57
|
+
return if @dh_params.nil?
|
|
58
|
+
@dh_params.to_pem
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# its('prime_length') { should be 2048 }
|
|
62
|
+
def prime_length
|
|
63
|
+
return if @dh_params.nil?
|
|
64
|
+
@dh_params.p.num_bits
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# its('text') { should eq 'human-readable-text' }
|
|
68
|
+
def text
|
|
69
|
+
return if @dh_params.nil?
|
|
70
|
+
@dh_params.to_text
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# it { should be_valid }
|
|
74
|
+
def valid?
|
|
75
|
+
return if @dh_params.nil?
|
|
76
|
+
@dh_params.params_ok?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def to_s
|
|
80
|
+
"dh_params #{@dh_params_path}"
|
|
81
|
+
end
|
|
82
|
+
end
|
data/lib/resources/directory.rb
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'resources/file'
|
|
4
|
-
|
|
5
|
-
module Inspec::Resources
|
|
6
|
-
class Directory < FileResource
|
|
7
|
-
name 'directory'
|
|
8
|
-
supports platform: 'unix'
|
|
9
|
-
supports platform: 'windows'
|
|
10
|
-
desc 'Use the directory InSpec audit resource to test if the file type is a directory. This is equivalent to using the file InSpec audit resource and the be_directory matcher, but provides a simpler and more direct way to test directories. All of the matchers available to file may be used with directory.'
|
|
11
|
-
example "
|
|
12
|
-
describe directory('path') do
|
|
13
|
-
it { should be_directory }
|
|
14
|
-
end
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
def exist?
|
|
18
|
-
file.exist? && file.directory?
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def to_s
|
|
22
|
-
"Directory #{source_path}"
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'resources/file'
|
|
4
|
+
|
|
5
|
+
module Inspec::Resources
|
|
6
|
+
class Directory < FileResource
|
|
7
|
+
name 'directory'
|
|
8
|
+
supports platform: 'unix'
|
|
9
|
+
supports platform: 'windows'
|
|
10
|
+
desc 'Use the directory InSpec audit resource to test if the file type is a directory. This is equivalent to using the file InSpec audit resource and the be_directory matcher, but provides a simpler and more direct way to test directories. All of the matchers available to file may be used with directory.'
|
|
11
|
+
example "
|
|
12
|
+
describe directory('path') do
|
|
13
|
+
it { should be_directory }
|
|
14
|
+
end
|
|
15
|
+
"
|
|
16
|
+
|
|
17
|
+
def exist?
|
|
18
|
+
file.exist? && file.directory?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_s
|
|
22
|
+
"Directory #{source_path}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/resources/docker.rb
CHANGED
|
@@ -1,236 +1,236 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
# Copyright 2017, Christoph Hartmann
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
require 'utils/filter'
|
|
7
|
-
require 'hashie/mash'
|
|
8
|
-
|
|
9
|
-
module Inspec::Resources
|
|
10
|
-
class DockerContainerFilter
|
|
11
|
-
# use filtertable for containers
|
|
12
|
-
filter = FilterTable.create
|
|
13
|
-
filter.add_accessor(:where)
|
|
14
|
-
.add_accessor(:entries)
|
|
15
|
-
.add(:commands, field: 'command')
|
|
16
|
-
.add(:ids, field: 'id')
|
|
17
|
-
.add(:images, field: 'image')
|
|
18
|
-
.add(:labels, field: 'labels')
|
|
19
|
-
.add(:local_volumes, field: 'localvolumes')
|
|
20
|
-
.add(:mounts, field: 'mounts')
|
|
21
|
-
.add(:names, field: 'names')
|
|
22
|
-
.add(:networks, field: 'networks')
|
|
23
|
-
.add(:ports, field: 'ports')
|
|
24
|
-
.add(:running_for, field: 'runningfor')
|
|
25
|
-
.add(:sizes, field: 'size')
|
|
26
|
-
.add(:status, field: 'status')
|
|
27
|
-
.add(:exists?) { |x| !x.entries.empty? }
|
|
28
|
-
.add(:running?) { |x|
|
|
29
|
-
x.where { status.downcase.start_with?('up') }
|
|
30
|
-
}
|
|
31
|
-
filter.connect(self, :containers)
|
|
32
|
-
|
|
33
|
-
attr_reader :containers
|
|
34
|
-
def initialize(containers)
|
|
35
|
-
@containers = containers
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class DockerImageFilter
|
|
40
|
-
filter = FilterTable.create
|
|
41
|
-
filter.add_accessor(:where)
|
|
42
|
-
.add_accessor(:entries)
|
|
43
|
-
.add(:ids, field: 'id')
|
|
44
|
-
.add(:repositories, field: 'repository')
|
|
45
|
-
.add(:tags, field: 'tag')
|
|
46
|
-
.add(:sizes, field: 'size')
|
|
47
|
-
.add(:digests, field: 'digest')
|
|
48
|
-
.add(:created, field: 'createdat')
|
|
49
|
-
.add(:created_since, field: 'createdsize')
|
|
50
|
-
.add(:exists?) { |x| !x.entries.empty? }
|
|
51
|
-
filter.connect(self, :images)
|
|
52
|
-
|
|
53
|
-
attr_reader :images
|
|
54
|
-
def initialize(images)
|
|
55
|
-
@images = images
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
class DockerServiceFilter
|
|
60
|
-
filter = FilterTable.create
|
|
61
|
-
filter.add_accessor(:where)
|
|
62
|
-
.add_accessor(:entries)
|
|
63
|
-
.add(:ids, field: 'id')
|
|
64
|
-
.add(:names, field: 'name')
|
|
65
|
-
.add(:modes, field: 'mode')
|
|
66
|
-
.add(:replicas, field: 'replicas')
|
|
67
|
-
.add(:images, field: 'image')
|
|
68
|
-
.add(:ports, field: 'ports')
|
|
69
|
-
.add(:exists?) { |x| !x.entries.empty? }
|
|
70
|
-
filter.connect(self, :services)
|
|
71
|
-
|
|
72
|
-
attr_reader :services
|
|
73
|
-
def initialize(services)
|
|
74
|
-
@services = services
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# This resource helps to parse information from the docker host
|
|
79
|
-
# For compatability with Serverspec we also offer the following resouses:
|
|
80
|
-
# - docker_container
|
|
81
|
-
# - docker_image
|
|
82
|
-
class Docker < Inspec.resource(1)
|
|
83
|
-
name 'docker'
|
|
84
|
-
supports platform: 'unix'
|
|
85
|
-
desc "
|
|
86
|
-
A resource to retrieve information about docker
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
example "
|
|
90
|
-
describe docker.containers do
|
|
91
|
-
its('images') { should_not include 'u12:latest' }
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
describe docker.images do
|
|
95
|
-
its('repositories') { should_not include 'inssecure_image' }
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
describe docker.services do
|
|
99
|
-
its('images') { should_not include 'inssecure_image' }
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
describe docker.version do
|
|
103
|
-
its('Server.Version') { should cmp >= '1.12'}
|
|
104
|
-
its('Client.Version') { should cmp >= '1.12'}
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
describe docker.object(id) do
|
|
108
|
-
its('Configuration.Path') { should eq 'value' }
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
docker.containers.ids.each do |id|
|
|
112
|
-
# call docker inspect for a specific container id
|
|
113
|
-
describe docker.object(id) do
|
|
114
|
-
its(%w(HostConfig Privileged)) { should cmp false }
|
|
115
|
-
its(%w(HostConfig Privileged)) { should_not cmp true }
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
"
|
|
119
|
-
|
|
120
|
-
def containers
|
|
121
|
-
DockerContainerFilter.new(parse_containers)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def images
|
|
125
|
-
DockerImageFilter.new(parse_images)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def services
|
|
129
|
-
DockerServiceFilter.new(parse_services)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def version
|
|
133
|
-
return @version if defined?(@version)
|
|
134
|
-
data = {}
|
|
135
|
-
cmd = inspec.command('docker version --format \'{{ json . }}\'')
|
|
136
|
-
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
|
|
137
|
-
@version = Hashie::Mash.new(data)
|
|
138
|
-
rescue JSON::ParserError => _e
|
|
139
|
-
return Hashie::Mash.new({})
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def info
|
|
143
|
-
return @info if defined?(@info)
|
|
144
|
-
data = {}
|
|
145
|
-
# docke info format is only supported for Docker 17.03+
|
|
146
|
-
cmd = inspec.command('docker info --format \'{{ json . }}\'')
|
|
147
|
-
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
|
|
148
|
-
@info = Hashie::Mash.new(data)
|
|
149
|
-
rescue JSON::ParserError => _e
|
|
150
|
-
return Hashie::Mash.new({})
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# returns information about docker objects
|
|
154
|
-
def object(id)
|
|
155
|
-
return @inspect if defined?(@inspect)
|
|
156
|
-
data = JSON.parse(inspec.command("docker inspect #{id}").stdout)
|
|
157
|
-
data = data[0] if data.is_a?(Array)
|
|
158
|
-
@inspect = Hashie::Mash.new(data)
|
|
159
|
-
rescue JSON::ParserError => _e
|
|
160
|
-
return Hashie::Mash.new({})
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def to_s
|
|
164
|
-
'Docker Host'
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
private
|
|
168
|
-
|
|
169
|
-
def parse_json_command(labels, subcommand)
|
|
170
|
-
# build command
|
|
171
|
-
format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
|
|
172
|
-
raw = inspec.command("docker #{subcommand} --format '{#{format.join(', ')}}'").stdout
|
|
173
|
-
output = []
|
|
174
|
-
# since docker is not outputting valid json, we need to parse each row
|
|
175
|
-
raw.each_line { |entry|
|
|
176
|
-
# convert all keys to lower_case to work well with ruby and filter table
|
|
177
|
-
j = JSON.parse(entry).map { |k, v|
|
|
178
|
-
[k.downcase, v]
|
|
179
|
-
}.to_h
|
|
180
|
-
|
|
181
|
-
# ensure all keys are there
|
|
182
|
-
j = ensure_keys(j, labels)
|
|
183
|
-
|
|
184
|
-
# strip off any linked container names
|
|
185
|
-
# Depending on how it was linked, the actual container name may come before
|
|
186
|
-
# or after the link information, so we'll just look for the first name that
|
|
187
|
-
# does not include a slash since that is not a valid character in a container name
|
|
188
|
-
j['names'] = j['names'].split(',').find { |c| !c.include?('/') } if j.key?('names')
|
|
189
|
-
|
|
190
|
-
output.push(j)
|
|
191
|
-
}
|
|
192
|
-
output
|
|
193
|
-
rescue JSON::ParserError => _e
|
|
194
|
-
warn "Could not parse `docker #{subcommand}` output"
|
|
195
|
-
[]
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def parse_containers
|
|
199
|
-
# @see https://github.com/moby/moby/issues/20625, works for docker 1.13+
|
|
200
|
-
# raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
|
|
201
|
-
# therefore we stick with older approach
|
|
202
|
-
labels = %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status}
|
|
203
|
-
|
|
204
|
-
# Networks LocalVolumes work with 1.13+ only
|
|
205
|
-
if !version.empty? && Gem::Version.new(version['Client']['Version']) >= Gem::Version.new('1.13')
|
|
206
|
-
labels.push('Networks')
|
|
207
|
-
labels.push('LocalVolumes')
|
|
208
|
-
end
|
|
209
|
-
parse_json_command(labels, 'ps -a --no-trunc')
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def parse_services
|
|
213
|
-
parse_json_command(%w{ID Name Mode Replicas Image Ports}, 'service ls')
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def ensure_keys(entry, labels)
|
|
217
|
-
labels.each { |key|
|
|
218
|
-
entry[key.downcase] = nil if !entry.key?(key.downcase)
|
|
219
|
-
}
|
|
220
|
-
entry
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def parse_images
|
|
224
|
-
# docker does not support the `json .` function here, therefore we need to emulate that behavior.
|
|
225
|
-
raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
|
|
226
|
-
c_images = []
|
|
227
|
-
raw_images.each_line { |entry|
|
|
228
|
-
c_images.push(JSON.parse(entry))
|
|
229
|
-
}
|
|
230
|
-
c_images
|
|
231
|
-
rescue JSON::ParserError => _e
|
|
232
|
-
warn 'Could not parse `docker images` output'
|
|
233
|
-
[]
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2017, Christoph Hartmann
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
require 'utils/filter'
|
|
7
|
+
require 'hashie/mash'
|
|
8
|
+
|
|
9
|
+
module Inspec::Resources
|
|
10
|
+
class DockerContainerFilter
|
|
11
|
+
# use filtertable for containers
|
|
12
|
+
filter = FilterTable.create
|
|
13
|
+
filter.add_accessor(:where)
|
|
14
|
+
.add_accessor(:entries)
|
|
15
|
+
.add(:commands, field: 'command')
|
|
16
|
+
.add(:ids, field: 'id')
|
|
17
|
+
.add(:images, field: 'image')
|
|
18
|
+
.add(:labels, field: 'labels')
|
|
19
|
+
.add(:local_volumes, field: 'localvolumes')
|
|
20
|
+
.add(:mounts, field: 'mounts')
|
|
21
|
+
.add(:names, field: 'names')
|
|
22
|
+
.add(:networks, field: 'networks')
|
|
23
|
+
.add(:ports, field: 'ports')
|
|
24
|
+
.add(:running_for, field: 'runningfor')
|
|
25
|
+
.add(:sizes, field: 'size')
|
|
26
|
+
.add(:status, field: 'status')
|
|
27
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
|
28
|
+
.add(:running?) { |x|
|
|
29
|
+
x.where { status.downcase.start_with?('up') }
|
|
30
|
+
}
|
|
31
|
+
filter.connect(self, :containers)
|
|
32
|
+
|
|
33
|
+
attr_reader :containers
|
|
34
|
+
def initialize(containers)
|
|
35
|
+
@containers = containers
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class DockerImageFilter
|
|
40
|
+
filter = FilterTable.create
|
|
41
|
+
filter.add_accessor(:where)
|
|
42
|
+
.add_accessor(:entries)
|
|
43
|
+
.add(:ids, field: 'id')
|
|
44
|
+
.add(:repositories, field: 'repository')
|
|
45
|
+
.add(:tags, field: 'tag')
|
|
46
|
+
.add(:sizes, field: 'size')
|
|
47
|
+
.add(:digests, field: 'digest')
|
|
48
|
+
.add(:created, field: 'createdat')
|
|
49
|
+
.add(:created_since, field: 'createdsize')
|
|
50
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
|
51
|
+
filter.connect(self, :images)
|
|
52
|
+
|
|
53
|
+
attr_reader :images
|
|
54
|
+
def initialize(images)
|
|
55
|
+
@images = images
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class DockerServiceFilter
|
|
60
|
+
filter = FilterTable.create
|
|
61
|
+
filter.add_accessor(:where)
|
|
62
|
+
.add_accessor(:entries)
|
|
63
|
+
.add(:ids, field: 'id')
|
|
64
|
+
.add(:names, field: 'name')
|
|
65
|
+
.add(:modes, field: 'mode')
|
|
66
|
+
.add(:replicas, field: 'replicas')
|
|
67
|
+
.add(:images, field: 'image')
|
|
68
|
+
.add(:ports, field: 'ports')
|
|
69
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
|
70
|
+
filter.connect(self, :services)
|
|
71
|
+
|
|
72
|
+
attr_reader :services
|
|
73
|
+
def initialize(services)
|
|
74
|
+
@services = services
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# This resource helps to parse information from the docker host
|
|
79
|
+
# For compatability with Serverspec we also offer the following resouses:
|
|
80
|
+
# - docker_container
|
|
81
|
+
# - docker_image
|
|
82
|
+
class Docker < Inspec.resource(1)
|
|
83
|
+
name 'docker'
|
|
84
|
+
supports platform: 'unix'
|
|
85
|
+
desc "
|
|
86
|
+
A resource to retrieve information about docker
|
|
87
|
+
"
|
|
88
|
+
|
|
89
|
+
example "
|
|
90
|
+
describe docker.containers do
|
|
91
|
+
its('images') { should_not include 'u12:latest' }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe docker.images do
|
|
95
|
+
its('repositories') { should_not include 'inssecure_image' }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe docker.services do
|
|
99
|
+
its('images') { should_not include 'inssecure_image' }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe docker.version do
|
|
103
|
+
its('Server.Version') { should cmp >= '1.12'}
|
|
104
|
+
its('Client.Version') { should cmp >= '1.12'}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe docker.object(id) do
|
|
108
|
+
its('Configuration.Path') { should eq 'value' }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
docker.containers.ids.each do |id|
|
|
112
|
+
# call docker inspect for a specific container id
|
|
113
|
+
describe docker.object(id) do
|
|
114
|
+
its(%w(HostConfig Privileged)) { should cmp false }
|
|
115
|
+
its(%w(HostConfig Privileged)) { should_not cmp true }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
"
|
|
119
|
+
|
|
120
|
+
def containers
|
|
121
|
+
DockerContainerFilter.new(parse_containers)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def images
|
|
125
|
+
DockerImageFilter.new(parse_images)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def services
|
|
129
|
+
DockerServiceFilter.new(parse_services)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def version
|
|
133
|
+
return @version if defined?(@version)
|
|
134
|
+
data = {}
|
|
135
|
+
cmd = inspec.command('docker version --format \'{{ json . }}\'')
|
|
136
|
+
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
|
|
137
|
+
@version = Hashie::Mash.new(data)
|
|
138
|
+
rescue JSON::ParserError => _e
|
|
139
|
+
return Hashie::Mash.new({})
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def info
|
|
143
|
+
return @info if defined?(@info)
|
|
144
|
+
data = {}
|
|
145
|
+
# docke info format is only supported for Docker 17.03+
|
|
146
|
+
cmd = inspec.command('docker info --format \'{{ json . }}\'')
|
|
147
|
+
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
|
|
148
|
+
@info = Hashie::Mash.new(data)
|
|
149
|
+
rescue JSON::ParserError => _e
|
|
150
|
+
return Hashie::Mash.new({})
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# returns information about docker objects
|
|
154
|
+
def object(id)
|
|
155
|
+
return @inspect if defined?(@inspect)
|
|
156
|
+
data = JSON.parse(inspec.command("docker inspect #{id}").stdout)
|
|
157
|
+
data = data[0] if data.is_a?(Array)
|
|
158
|
+
@inspect = Hashie::Mash.new(data)
|
|
159
|
+
rescue JSON::ParserError => _e
|
|
160
|
+
return Hashie::Mash.new({})
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def to_s
|
|
164
|
+
'Docker Host'
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
def parse_json_command(labels, subcommand)
|
|
170
|
+
# build command
|
|
171
|
+
format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
|
|
172
|
+
raw = inspec.command("docker #{subcommand} --format '{#{format.join(', ')}}'").stdout
|
|
173
|
+
output = []
|
|
174
|
+
# since docker is not outputting valid json, we need to parse each row
|
|
175
|
+
raw.each_line { |entry|
|
|
176
|
+
# convert all keys to lower_case to work well with ruby and filter table
|
|
177
|
+
j = JSON.parse(entry).map { |k, v|
|
|
178
|
+
[k.downcase, v]
|
|
179
|
+
}.to_h
|
|
180
|
+
|
|
181
|
+
# ensure all keys are there
|
|
182
|
+
j = ensure_keys(j, labels)
|
|
183
|
+
|
|
184
|
+
# strip off any linked container names
|
|
185
|
+
# Depending on how it was linked, the actual container name may come before
|
|
186
|
+
# or after the link information, so we'll just look for the first name that
|
|
187
|
+
# does not include a slash since that is not a valid character in a container name
|
|
188
|
+
j['names'] = j['names'].split(',').find { |c| !c.include?('/') } if j.key?('names')
|
|
189
|
+
|
|
190
|
+
output.push(j)
|
|
191
|
+
}
|
|
192
|
+
output
|
|
193
|
+
rescue JSON::ParserError => _e
|
|
194
|
+
warn "Could not parse `docker #{subcommand}` output"
|
|
195
|
+
[]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def parse_containers
|
|
199
|
+
# @see https://github.com/moby/moby/issues/20625, works for docker 1.13+
|
|
200
|
+
# raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
|
|
201
|
+
# therefore we stick with older approach
|
|
202
|
+
labels = %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status}
|
|
203
|
+
|
|
204
|
+
# Networks LocalVolumes work with 1.13+ only
|
|
205
|
+
if !version.empty? && Gem::Version.new(version['Client']['Version']) >= Gem::Version.new('1.13')
|
|
206
|
+
labels.push('Networks')
|
|
207
|
+
labels.push('LocalVolumes')
|
|
208
|
+
end
|
|
209
|
+
parse_json_command(labels, 'ps -a --no-trunc')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def parse_services
|
|
213
|
+
parse_json_command(%w{ID Name Mode Replicas Image Ports}, 'service ls')
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def ensure_keys(entry, labels)
|
|
217
|
+
labels.each { |key|
|
|
218
|
+
entry[key.downcase] = nil if !entry.key?(key.downcase)
|
|
219
|
+
}
|
|
220
|
+
entry
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def parse_images
|
|
224
|
+
# docker does not support the `json .` function here, therefore we need to emulate that behavior.
|
|
225
|
+
raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
|
|
226
|
+
c_images = []
|
|
227
|
+
raw_images.each_line { |entry|
|
|
228
|
+
c_images.push(JSON.parse(entry))
|
|
229
|
+
}
|
|
230
|
+
c_images
|
|
231
|
+
rescue JSON::ParserError => _e
|
|
232
|
+
warn 'Could not parse `docker images` output'
|
|
233
|
+
[]
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|