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
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
class AwsVpc < Inspec.resource(1)
|
|
2
|
-
name 'aws_vpc'
|
|
3
|
-
desc 'Verifies settings for AWS VPC'
|
|
4
|
-
example "
|
|
5
|
-
describe aws_vpc do
|
|
6
|
-
it { should be_default }
|
|
7
|
-
its('cidr_block') { should cmp '10.0.0.0/16' }
|
|
8
|
-
end
|
|
9
|
-
"
|
|
10
|
-
supports platform: 'aws'
|
|
11
|
-
|
|
12
|
-
include AwsSingularResourceMixin
|
|
13
|
-
|
|
14
|
-
def to_s
|
|
15
|
-
"VPC #{vpc_id}"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
[:cidr_block, :dhcp_options_id, :state, :vpc_id, :instance_tenancy, :is_default].each do |property|
|
|
19
|
-
define_method(property) do
|
|
20
|
-
@vpc[property]
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
alias default? is_default
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def validate_params(raw_params)
|
|
29
|
-
validated_params = check_resource_param_names(
|
|
30
|
-
raw_params: raw_params,
|
|
31
|
-
allowed_params: [:vpc_id],
|
|
32
|
-
allowed_scalar_name: :vpc_id,
|
|
33
|
-
allowed_scalar_type: String,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
if validated_params.key?(:vpc_id) && validated_params[:vpc_id] !~ /^vpc\-[0-9a-f]{8}/
|
|
37
|
-
raise ArgumentError, 'aws_vpc VPC ID must be in the format "vpc-" followed by 8 hexadecimal characters.'
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
validated_params
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def fetch_from_api
|
|
44
|
-
backend = BackendFactory.create(inspec_runner)
|
|
45
|
-
|
|
46
|
-
if @vpc_id.nil?
|
|
47
|
-
filter = { name: 'isDefault', values: ['true'] }
|
|
48
|
-
else
|
|
49
|
-
filter = { name: 'vpc-id', values: [@vpc_id] }
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
resp = backend.describe_vpcs({ filters: [filter] })
|
|
53
|
-
|
|
54
|
-
@vpc = resp.vpcs[0].to_h
|
|
55
|
-
@vpc_id = @vpc[:vpc_id]
|
|
56
|
-
@exists = !@vpc.empty?
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
class Backend
|
|
60
|
-
class AwsClientApi < AwsBackendBase
|
|
61
|
-
BackendFactory.set_default_backend(self)
|
|
62
|
-
self.aws_client_class = Aws::EC2::Client
|
|
63
|
-
|
|
64
|
-
def describe_vpcs(query)
|
|
65
|
-
aws_service_client.describe_vpcs(query)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
1
|
+
class AwsVpc < Inspec.resource(1)
|
|
2
|
+
name 'aws_vpc'
|
|
3
|
+
desc 'Verifies settings for AWS VPC'
|
|
4
|
+
example "
|
|
5
|
+
describe aws_vpc do
|
|
6
|
+
it { should be_default }
|
|
7
|
+
its('cidr_block') { should cmp '10.0.0.0/16' }
|
|
8
|
+
end
|
|
9
|
+
"
|
|
10
|
+
supports platform: 'aws'
|
|
11
|
+
|
|
12
|
+
include AwsSingularResourceMixin
|
|
13
|
+
|
|
14
|
+
def to_s
|
|
15
|
+
"VPC #{vpc_id}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
[:cidr_block, :dhcp_options_id, :state, :vpc_id, :instance_tenancy, :is_default].each do |property|
|
|
19
|
+
define_method(property) do
|
|
20
|
+
@vpc[property]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
alias default? is_default
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def validate_params(raw_params)
|
|
29
|
+
validated_params = check_resource_param_names(
|
|
30
|
+
raw_params: raw_params,
|
|
31
|
+
allowed_params: [:vpc_id],
|
|
32
|
+
allowed_scalar_name: :vpc_id,
|
|
33
|
+
allowed_scalar_type: String,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if validated_params.key?(:vpc_id) && validated_params[:vpc_id] !~ /^vpc\-[0-9a-f]{8}/
|
|
37
|
+
raise ArgumentError, 'aws_vpc VPC ID must be in the format "vpc-" followed by 8 hexadecimal characters.'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
validated_params
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def fetch_from_api
|
|
44
|
+
backend = BackendFactory.create(inspec_runner)
|
|
45
|
+
|
|
46
|
+
if @vpc_id.nil?
|
|
47
|
+
filter = { name: 'isDefault', values: ['true'] }
|
|
48
|
+
else
|
|
49
|
+
filter = { name: 'vpc-id', values: [@vpc_id] }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
resp = backend.describe_vpcs({ filters: [filter] })
|
|
53
|
+
|
|
54
|
+
@vpc = resp.vpcs[0].to_h
|
|
55
|
+
@vpc_id = @vpc[:vpc_id]
|
|
56
|
+
@exists = !@vpc.empty?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class Backend
|
|
60
|
+
class AwsClientApi < AwsBackendBase
|
|
61
|
+
BackendFactory.set_default_backend(self)
|
|
62
|
+
self.aws_client_class = Aws::EC2::Client
|
|
63
|
+
|
|
64
|
+
def describe_vpcs(query)
|
|
65
|
+
aws_service_client.describe_vpcs(query)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
class AwsVpcs < Inspec.resource(1)
|
|
2
|
-
name 'aws_vpcs'
|
|
3
|
-
desc 'Verifies settings for AWS VPCs in bulk'
|
|
4
|
-
example '
|
|
5
|
-
describe aws_vpcs do
|
|
6
|
-
it { should exist }
|
|
7
|
-
end
|
|
8
|
-
'
|
|
9
|
-
supports platform: 'aws'
|
|
10
|
-
|
|
11
|
-
include AwsPluralResourceMixin
|
|
12
|
-
|
|
13
|
-
# Underlying FilterTable implementation.
|
|
14
|
-
filter = FilterTable.create
|
|
15
|
-
filter.add_accessor(:entries)
|
|
16
|
-
.add(:exists?) { |x| !x.entries.empty? }
|
|
17
|
-
filter.connect(self, :table)
|
|
18
|
-
|
|
19
|
-
def validate_params(raw_params)
|
|
20
|
-
# No params yet
|
|
21
|
-
unless raw_params.empty?
|
|
22
|
-
raise ArgumentError, 'aws_vpcs does not accept resource parameters'
|
|
23
|
-
end
|
|
24
|
-
raw_params
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def to_s
|
|
28
|
-
'VPCs'
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def fetch_from_api
|
|
32
|
-
@table = BackendFactory.create(inspec_runner).describe_vpcs.to_h[:vpcs]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
class Backend
|
|
36
|
-
class AwsClientApi < AwsBackendBase
|
|
37
|
-
BackendFactory.set_default_backend(self)
|
|
38
|
-
self.aws_client_class = Aws::EC2::Client
|
|
39
|
-
|
|
40
|
-
def describe_vpcs(query = {})
|
|
41
|
-
aws_service_client.describe_vpcs(query)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
1
|
+
class AwsVpcs < Inspec.resource(1)
|
|
2
|
+
name 'aws_vpcs'
|
|
3
|
+
desc 'Verifies settings for AWS VPCs in bulk'
|
|
4
|
+
example '
|
|
5
|
+
describe aws_vpcs do
|
|
6
|
+
it { should exist }
|
|
7
|
+
end
|
|
8
|
+
'
|
|
9
|
+
supports platform: 'aws'
|
|
10
|
+
|
|
11
|
+
include AwsPluralResourceMixin
|
|
12
|
+
|
|
13
|
+
# Underlying FilterTable implementation.
|
|
14
|
+
filter = FilterTable.create
|
|
15
|
+
filter.add_accessor(:entries)
|
|
16
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
|
17
|
+
filter.connect(self, :table)
|
|
18
|
+
|
|
19
|
+
def validate_params(raw_params)
|
|
20
|
+
# No params yet
|
|
21
|
+
unless raw_params.empty?
|
|
22
|
+
raise ArgumentError, 'aws_vpcs does not accept resource parameters'
|
|
23
|
+
end
|
|
24
|
+
raw_params
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
'VPCs'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fetch_from_api
|
|
32
|
+
@table = BackendFactory.create(inspec_runner).describe_vpcs.to_h[:vpcs]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Backend
|
|
36
|
+
class AwsClientApi < AwsBackendBase
|
|
37
|
+
BackendFactory.set_default_backend(self)
|
|
38
|
+
self.aws_client_class = Aws::EC2::Client
|
|
39
|
+
|
|
40
|
+
def describe_vpcs(query = {})
|
|
41
|
+
aws_service_client.describe_vpcs(query)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -1,377 +1,377 @@
|
|
|
1
|
-
# Base class for Azure Resources. This allows the generic class to work
|
|
2
|
-
# as well as the specific target resources for Azure Resources
|
|
3
|
-
#
|
|
4
|
-
# @author Russell Seymour
|
|
5
|
-
module Inspec::Resources
|
|
6
|
-
class AzureResourceBase < Inspec.resource(1)
|
|
7
|
-
attr_reader :opts, :client, :azure
|
|
8
|
-
|
|
9
|
-
# Constructor that retreives the specified resource
|
|
10
|
-
#
|
|
11
|
-
# The opts hash should contain the following
|
|
12
|
-
# :group_name - name of the resource group in which to look for items
|
|
13
|
-
# :type - the type of Azure resource to look for
|
|
14
|
-
# :apiversion - API version to use when looking for a specific resource
|
|
15
|
-
# :name - name of the resource to find
|
|
16
|
-
#
|
|
17
|
-
# @author Russell Seymour
|
|
18
|
-
#
|
|
19
|
-
# @param [Hash] opts Hashtable of options as highlighted above
|
|
20
|
-
# rubocop:disable Metrics/AbcSize
|
|
21
|
-
def initialize(opts)
|
|
22
|
-
# declare the hashtable of counts
|
|
23
|
-
@counts = {}
|
|
24
|
-
@total = 0
|
|
25
|
-
@opts = opts
|
|
26
|
-
|
|
27
|
-
# Determine if the environment variables for the options have been set
|
|
28
|
-
option_var_names = {
|
|
29
|
-
group_name: 'AZURE_RESOURCE_GROUP_NAME',
|
|
30
|
-
name: 'AZURE_RESOURCE_NAME',
|
|
31
|
-
type: 'AZURE_RESOURCE_TYPE',
|
|
32
|
-
apiversion: 'AZURE_RESOURCE_API_VERSION',
|
|
33
|
-
}
|
|
34
|
-
option_var_names.each do |option_name, env_var_name|
|
|
35
|
-
opts[option_name] = ENV[env_var_name] unless ENV[env_var_name].nil?
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
@azure = inspec.backend
|
|
39
|
-
@client = azure.azure_client
|
|
40
|
-
@failed_resource = false
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def failed_resource?
|
|
44
|
-
@failed_resource
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def catch_azure_errors
|
|
48
|
-
yield
|
|
49
|
-
rescue MsRestAzure::AzureOperationError => e
|
|
50
|
-
# e.message is actually a massive stringified JSON, which might be useful in the future.
|
|
51
|
-
# You want error_message here.
|
|
52
|
-
fail_resource e.error_message
|
|
53
|
-
@failed_resource = true
|
|
54
|
-
nil
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Return information about the resource group
|
|
58
|
-
def resource_group
|
|
59
|
-
catch_azure_errors do
|
|
60
|
-
resource_group = client.resource_groups.get(opts[:group_name])
|
|
61
|
-
|
|
62
|
-
# create the methods for the resource group object
|
|
63
|
-
dm = AzureResourceDynamicMethods.new
|
|
64
|
-
dm.create_methods(self, resource_group)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def resources
|
|
69
|
-
resources = nil
|
|
70
|
-
catch_azure_errors do
|
|
71
|
-
resources = client.resources.list_by_resource_group(opts[:group_name])
|
|
72
|
-
end
|
|
73
|
-
return if failed_resource?
|
|
74
|
-
|
|
75
|
-
# filter the resources based on the type, and the name if they been specified
|
|
76
|
-
resources = filter_resources(resources, opts)
|
|
77
|
-
|
|
78
|
-
# if there is one resource then define methods on this class
|
|
79
|
-
if resources.count == 1
|
|
80
|
-
@total = 1
|
|
81
|
-
|
|
82
|
-
resource = nil
|
|
83
|
-
catch_azure_errors do
|
|
84
|
-
# get the apiversion for the resource, if one has not been specified
|
|
85
|
-
apiversion = azure.get_api_version(resources[0].type, opts)
|
|
86
|
-
|
|
87
|
-
# get the resource by id so it can be interrogated
|
|
88
|
-
resource = client.resources.get_by_id(resources[0].id, apiversion)
|
|
89
|
-
end
|
|
90
|
-
return if failed_resource?
|
|
91
|
-
|
|
92
|
-
dm = AzureResourceDynamicMethods.new
|
|
93
|
-
|
|
94
|
-
dm.create_methods(self, resource)
|
|
95
|
-
else
|
|
96
|
-
|
|
97
|
-
# As there are many resources, parse each one so that it can be
|
|
98
|
-
# interrogated by the FilterTable
|
|
99
|
-
# @probes = parse_resources(resources, azure)
|
|
100
|
-
@probes = resources.each.map do |item|
|
|
101
|
-
# update the total
|
|
102
|
-
@total += 1
|
|
103
|
-
|
|
104
|
-
# determine the counts for each type
|
|
105
|
-
namespace, type_name = item.type.split(/\./)
|
|
106
|
-
counts.key?(namespace) ? false : counts[namespace] = {}
|
|
107
|
-
counts[namespace].key?(type_name) ? counts[namespace][type_name] += 1 : counts[namespace][type_name] = 1
|
|
108
|
-
|
|
109
|
-
# get the detail about the resource
|
|
110
|
-
apiversion = azure.get_api_version(item.type, opts)
|
|
111
|
-
resource = client.resources.get_by_id(item.id, apiversion)
|
|
112
|
-
|
|
113
|
-
# parse the resource
|
|
114
|
-
parse_resource(resource)
|
|
115
|
-
end.compact
|
|
116
|
-
|
|
117
|
-
# Iterate around the counts and create the necessary classes
|
|
118
|
-
counts.each do |namespace, ns_counts|
|
|
119
|
-
define_singleton_method namespace do
|
|
120
|
-
AzureResourceTypeCounts.new(ns_counts)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Does the resource have any tags?
|
|
127
|
-
#
|
|
128
|
-
# If it is a Hashtable then it does not, because there was nothing to parse so there is not
|
|
129
|
-
# a nested object to work with
|
|
130
|
-
#
|
|
131
|
-
# @author Russell Seymour
|
|
132
|
-
def has_tags?
|
|
133
|
-
tags.is_a?(Hash) ? false : true
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Returns how many tags have been set on the resource
|
|
137
|
-
#
|
|
138
|
-
# @author Russell Seymour
|
|
139
|
-
def tag_count
|
|
140
|
-
tags.count
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# It is necessary to be able to test the tags of a resource. It is possible to say of the
|
|
144
|
-
# resource has tags or not, and it is possible to check that the tags include a specific tag
|
|
145
|
-
# However the value is not accessible, this function creates methods for all the tags that
|
|
146
|
-
# are available.
|
|
147
|
-
#
|
|
148
|
-
# The format of the method name is '<TAG_NAME>_tag' and will return the value of that tag
|
|
149
|
-
#
|
|
150
|
-
# Disabling rubopcop check. If this is set as a normal if..then..end statement there is a
|
|
151
|
-
# violation stating it should use a guard. When using a guard it throws this error
|
|
152
|
-
#
|
|
153
|
-
# @author Russell Seymour
|
|
154
|
-
def create_tag_methods
|
|
155
|
-
# Iterate around the items of the tags and create the necessary access methods
|
|
156
|
-
tags.item.each do |name, value|
|
|
157
|
-
method_name = format('%s_tag', name)
|
|
158
|
-
define_singleton_method method_name do
|
|
159
|
-
value
|
|
160
|
-
end
|
|
161
|
-
end if defined?(tags.item)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
private
|
|
165
|
-
|
|
166
|
-
# Filter the resources that are returned by the options that have been specified
|
|
167
|
-
#
|
|
168
|
-
def filter_resources(resources, opts)
|
|
169
|
-
if opts[:type] && opts[:name]
|
|
170
|
-
resources.select { |r| r.type == opts[:type] && r.name == opts[:name] }
|
|
171
|
-
elsif opts[:type]
|
|
172
|
-
resources.select { |r| r.type == opts[:type] }
|
|
173
|
-
elsif opts[:name]
|
|
174
|
-
resources.select { |r| r.name == opts[:name] }
|
|
175
|
-
else
|
|
176
|
-
resources
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
# Class to create methods on the calling object at run time.
|
|
183
|
-
# Each of the Azure Resources have different attributes and properties, and they all need
|
|
184
|
-
# to be testable. To do this no methods are hardcoded, each on is craeted based on the
|
|
185
|
-
# information returned from Azure.
|
|
186
|
-
#
|
|
187
|
-
# The class is a helper class essentially as it creates the methods on the calling class
|
|
188
|
-
# rather than itself. This means that there is less duplication of code and it can be
|
|
189
|
-
# reused easily.
|
|
190
|
-
#
|
|
191
|
-
# @author Russell Seymour
|
|
192
|
-
# @since 0.2.0
|
|
193
|
-
class AzureResourceDynamicMethods
|
|
194
|
-
# Given the calling object and its data, create the methods on the object according
|
|
195
|
-
# to the data that has been retrieved. Various types of data can be returned so the method
|
|
196
|
-
# checks the type to ensure that the necessary methods are configured correctly
|
|
197
|
-
#
|
|
198
|
-
# @param AzureResourceProbe|AzureResource object The object on which the methods should be craeted
|
|
199
|
-
# @param variant data The data from which the methods should be created
|
|
200
|
-
def create_methods(object, data)
|
|
201
|
-
# Check the type of data as this affects the setup of the methods
|
|
202
|
-
# If it is an Azure Generic Resource then setup methods for each of
|
|
203
|
-
# the instance variables
|
|
204
|
-
case data.class.to_s
|
|
205
|
-
when /^Azure::Resources::Mgmt::.*::Models::GenericResource$/,
|
|
206
|
-
/^Azure::Resources::Mgmt::.*::Models::ResourceGroup$/
|
|
207
|
-
# iterate around the instance variables
|
|
208
|
-
data.instance_variables.each do |var|
|
|
209
|
-
create_method(object, var.to_s.delete('@'), data.instance_variable_get(var))
|
|
210
|
-
end
|
|
211
|
-
# When the data is a Hash object iterate around each of the key value pairs and
|
|
212
|
-
# craete a method for each one.
|
|
213
|
-
when 'Hash'
|
|
214
|
-
data.each do |key, value|
|
|
215
|
-
create_method(object, key, value)
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
private
|
|
221
|
-
|
|
222
|
-
# Method that is responsible for creating the method on the calling object. This is
|
|
223
|
-
# because some nesting maybe required. For example of the value is a Hash then it will
|
|
224
|
-
# need to have an AzureResourceProbe create for each key, whereas if it is a simple
|
|
225
|
-
# string then the value just needs to be returned
|
|
226
|
-
#
|
|
227
|
-
# @private
|
|
228
|
-
#
|
|
229
|
-
# @param AzureResourceProbe|AzureResource object Object on which the methods need to be created
|
|
230
|
-
# @param string name The name of the method
|
|
231
|
-
# @param variant value The value that needs to be returned by the method
|
|
232
|
-
def create_method(object, name, value)
|
|
233
|
-
# Create the necessary method based on the var that has been passed
|
|
234
|
-
# Test the value for its type so that the method can be setup correctly
|
|
235
|
-
case value.class.to_s
|
|
236
|
-
when 'String', 'Integer', 'TrueClass', 'FalseClass', 'Fixnum'
|
|
237
|
-
object.define_singleton_method name do
|
|
238
|
-
value
|
|
239
|
-
end
|
|
240
|
-
when 'Hash'
|
|
241
|
-
value.count.zero? ? return_value = value : return_value = AzureResourceProbe.new(value)
|
|
242
|
-
object.define_singleton_method name do
|
|
243
|
-
return_value
|
|
244
|
-
end
|
|
245
|
-
when /^Azure::Resources::Mgmt::.*::Models::ResourceGroupProperties$/
|
|
246
|
-
# This is a special case where the properties of the resource group is not a simple JSON model
|
|
247
|
-
# This is because the plugin is using the Azure SDK to get this information so it is an SDK object
|
|
248
|
-
# that has to be interrogated in a different way. This is the only object type that behaves like this
|
|
249
|
-
value.instance_variables.each do |var|
|
|
250
|
-
create_method(object, var.to_s.delete('@'), value.instance_variable_get(var))
|
|
251
|
-
end
|
|
252
|
-
when 'Array'
|
|
253
|
-
# Some things are just string or integer arrays
|
|
254
|
-
# Check this by seeing if the first element is a string / integer / boolean or
|
|
255
|
-
# a hashtable
|
|
256
|
-
# This may not be the best methid, but short of testing all elements in the array, this is
|
|
257
|
-
# the quickest test
|
|
258
|
-
case value[0].class.to_s
|
|
259
|
-
when 'String', 'Integer', 'TrueClass', 'FalseClass', 'Fixnum'
|
|
260
|
-
probes = value
|
|
261
|
-
else
|
|
262
|
-
probes = []
|
|
263
|
-
value.each do |value_item|
|
|
264
|
-
probes << AzureResourceProbe.new(value_item)
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
object.define_singleton_method name do
|
|
268
|
-
probes
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
# Class object to maintain a count of the Azure Resource types that are found
|
|
275
|
-
# when a less specific test is carried out. For example if all the resoures of a resource
|
|
276
|
-
# group are called for, there will be variaous types and number of those types.
|
|
277
|
-
#
|
|
278
|
-
# Each type is namespaced, so for example a virtual machine has the type 'Microsoft.Compute/virtualMachines'
|
|
279
|
-
# This is broken down into the 'Microsoft' class with the type 'Compute/virtualMachines'
|
|
280
|
-
# This has been done for two reasons:
|
|
281
|
-
# 1. Enable the dotted notation to work in the test
|
|
282
|
-
# 2. Allow third party resource types ot be catered for if they are ever enabled by Microsoft
|
|
283
|
-
#
|
|
284
|
-
# @author Russell Seymour
|
|
285
|
-
# @since 0.2.0
|
|
286
|
-
class AzureResourceTypeCounts
|
|
287
|
-
# Constructor to setup a new class for a specific Azure Resource type.
|
|
288
|
-
# It should be passed a hashtable with information such as:
|
|
289
|
-
# {
|
|
290
|
-
# "Compute/virtualMachines" => 2,
|
|
291
|
-
# "Network/networkInterfaces" => 3
|
|
292
|
-
# }
|
|
293
|
-
# This will result in two methods being created on the class:
|
|
294
|
-
# - Compute/virtualNetworks
|
|
295
|
-
# - Network/networkInterfaces
|
|
296
|
-
# Each of which will return the corresponding count value
|
|
297
|
-
#
|
|
298
|
-
# @param Hash counts Hash table of types and the count of each one
|
|
299
|
-
#
|
|
300
|
-
# @return AzureResourceTypeCounts
|
|
301
|
-
def initialize(counts)
|
|
302
|
-
counts.each do |type, count|
|
|
303
|
-
define_singleton_method type do
|
|
304
|
-
count
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
# Class object that is created for each element that is returned by Azure.
|
|
311
|
-
# This is what is interogated by Inspec. If they are nested hashes, then this results
|
|
312
|
-
# in nested AzureResourceProbe objects.
|
|
313
|
-
#
|
|
314
|
-
# For example, if the following was seen in an Azure Resource
|
|
315
|
-
# properties -> storageProfile -> imageReference
|
|
316
|
-
# Would result in the following nestec classes
|
|
317
|
-
# AzureResource -> AzureResourceProbe -> AzureResourceProbe
|
|
318
|
-
#
|
|
319
|
-
# The methods for each of the classes are dynamically defined at run time and will
|
|
320
|
-
# match the items that are retrieved from Azure. See the 'test/integration/verify/controls' for
|
|
321
|
-
# examples
|
|
322
|
-
#
|
|
323
|
-
# This class will not be called externally
|
|
324
|
-
#
|
|
325
|
-
# @author Russell Seymour
|
|
326
|
-
# @since 0.2.0
|
|
327
|
-
# @attr_reader string name Name of the Azure resource
|
|
328
|
-
# @attr_reader string type Type of the Azure Resource
|
|
329
|
-
# @attr_reader string location Location in Azure of the resource
|
|
330
|
-
class AzureResourceProbe
|
|
331
|
-
attr_reader :name, :type, :location, :item, :count
|
|
332
|
-
|
|
333
|
-
# Initialize method for the class. Accepts an item, be it a scalar value, hash or Azure object
|
|
334
|
-
# It will then create the necessary dynamic methods so that they can be called in the tests
|
|
335
|
-
# This is accomplished by call the AzureResourceDynamicMethods
|
|
336
|
-
#
|
|
337
|
-
# @param varaint The item from which the class will be initialized
|
|
338
|
-
#
|
|
339
|
-
# @return AzureResourceProbe
|
|
340
|
-
def initialize(item)
|
|
341
|
-
dm = AzureResourceDynamicMethods.new
|
|
342
|
-
dm.create_methods(self, item)
|
|
343
|
-
|
|
344
|
-
# Set the item as a property on the class
|
|
345
|
-
# This is so that it is possible to interrogate what has been added to the class and isolate them from
|
|
346
|
-
# the standard methods that a Ruby class has.
|
|
347
|
-
# This used for checking Tags on a resource for example
|
|
348
|
-
# It also allows direct access if so required
|
|
349
|
-
@item = item
|
|
350
|
-
|
|
351
|
-
# Set how many items have been set
|
|
352
|
-
@count = item.length
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
# Allows resources to respond to the include test
|
|
356
|
-
# This means that things like tags can be checked for and then their value tested
|
|
357
|
-
#
|
|
358
|
-
# @author Russell Seymour
|
|
359
|
-
#
|
|
360
|
-
# @param [String] key Name of the item to look for in the @item property
|
|
361
|
-
def include?(key)
|
|
362
|
-
@item.key?(key)
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
# Give a sting like `computer_name` return the camelCase version, e.g.
|
|
366
|
-
# computerName
|
|
367
|
-
#
|
|
368
|
-
# @param string data Data that needs to be converted from snake_case to camelCase
|
|
369
|
-
#
|
|
370
|
-
# @return string
|
|
371
|
-
def camel_case(data)
|
|
372
|
-
camel_case_data = data.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
|
373
|
-
|
|
374
|
-
# Ensure that gb (as in gigabytes) is uppercased
|
|
375
|
-
camel_case_data.gsub(/[gb]/, &:upcase)
|
|
376
|
-
end
|
|
377
|
-
end
|
|
1
|
+
# Base class for Azure Resources. This allows the generic class to work
|
|
2
|
+
# as well as the specific target resources for Azure Resources
|
|
3
|
+
#
|
|
4
|
+
# @author Russell Seymour
|
|
5
|
+
module Inspec::Resources
|
|
6
|
+
class AzureResourceBase < Inspec.resource(1)
|
|
7
|
+
attr_reader :opts, :client, :azure
|
|
8
|
+
|
|
9
|
+
# Constructor that retreives the specified resource
|
|
10
|
+
#
|
|
11
|
+
# The opts hash should contain the following
|
|
12
|
+
# :group_name - name of the resource group in which to look for items
|
|
13
|
+
# :type - the type of Azure resource to look for
|
|
14
|
+
# :apiversion - API version to use when looking for a specific resource
|
|
15
|
+
# :name - name of the resource to find
|
|
16
|
+
#
|
|
17
|
+
# @author Russell Seymour
|
|
18
|
+
#
|
|
19
|
+
# @param [Hash] opts Hashtable of options as highlighted above
|
|
20
|
+
# rubocop:disable Metrics/AbcSize
|
|
21
|
+
def initialize(opts)
|
|
22
|
+
# declare the hashtable of counts
|
|
23
|
+
@counts = {}
|
|
24
|
+
@total = 0
|
|
25
|
+
@opts = opts
|
|
26
|
+
|
|
27
|
+
# Determine if the environment variables for the options have been set
|
|
28
|
+
option_var_names = {
|
|
29
|
+
group_name: 'AZURE_RESOURCE_GROUP_NAME',
|
|
30
|
+
name: 'AZURE_RESOURCE_NAME',
|
|
31
|
+
type: 'AZURE_RESOURCE_TYPE',
|
|
32
|
+
apiversion: 'AZURE_RESOURCE_API_VERSION',
|
|
33
|
+
}
|
|
34
|
+
option_var_names.each do |option_name, env_var_name|
|
|
35
|
+
opts[option_name] = ENV[env_var_name] unless ENV[env_var_name].nil?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@azure = inspec.backend
|
|
39
|
+
@client = azure.azure_client
|
|
40
|
+
@failed_resource = false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def failed_resource?
|
|
44
|
+
@failed_resource
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def catch_azure_errors
|
|
48
|
+
yield
|
|
49
|
+
rescue MsRestAzure::AzureOperationError => e
|
|
50
|
+
# e.message is actually a massive stringified JSON, which might be useful in the future.
|
|
51
|
+
# You want error_message here.
|
|
52
|
+
fail_resource e.error_message
|
|
53
|
+
@failed_resource = true
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Return information about the resource group
|
|
58
|
+
def resource_group
|
|
59
|
+
catch_azure_errors do
|
|
60
|
+
resource_group = client.resource_groups.get(opts[:group_name])
|
|
61
|
+
|
|
62
|
+
# create the methods for the resource group object
|
|
63
|
+
dm = AzureResourceDynamicMethods.new
|
|
64
|
+
dm.create_methods(self, resource_group)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def resources
|
|
69
|
+
resources = nil
|
|
70
|
+
catch_azure_errors do
|
|
71
|
+
resources = client.resources.list_by_resource_group(opts[:group_name])
|
|
72
|
+
end
|
|
73
|
+
return if failed_resource?
|
|
74
|
+
|
|
75
|
+
# filter the resources based on the type, and the name if they been specified
|
|
76
|
+
resources = filter_resources(resources, opts)
|
|
77
|
+
|
|
78
|
+
# if there is one resource then define methods on this class
|
|
79
|
+
if resources.count == 1
|
|
80
|
+
@total = 1
|
|
81
|
+
|
|
82
|
+
resource = nil
|
|
83
|
+
catch_azure_errors do
|
|
84
|
+
# get the apiversion for the resource, if one has not been specified
|
|
85
|
+
apiversion = azure.get_api_version(resources[0].type, opts)
|
|
86
|
+
|
|
87
|
+
# get the resource by id so it can be interrogated
|
|
88
|
+
resource = client.resources.get_by_id(resources[0].id, apiversion)
|
|
89
|
+
end
|
|
90
|
+
return if failed_resource?
|
|
91
|
+
|
|
92
|
+
dm = AzureResourceDynamicMethods.new
|
|
93
|
+
|
|
94
|
+
dm.create_methods(self, resource)
|
|
95
|
+
else
|
|
96
|
+
|
|
97
|
+
# As there are many resources, parse each one so that it can be
|
|
98
|
+
# interrogated by the FilterTable
|
|
99
|
+
# @probes = parse_resources(resources, azure)
|
|
100
|
+
@probes = resources.each.map do |item|
|
|
101
|
+
# update the total
|
|
102
|
+
@total += 1
|
|
103
|
+
|
|
104
|
+
# determine the counts for each type
|
|
105
|
+
namespace, type_name = item.type.split(/\./)
|
|
106
|
+
counts.key?(namespace) ? false : counts[namespace] = {}
|
|
107
|
+
counts[namespace].key?(type_name) ? counts[namespace][type_name] += 1 : counts[namespace][type_name] = 1
|
|
108
|
+
|
|
109
|
+
# get the detail about the resource
|
|
110
|
+
apiversion = azure.get_api_version(item.type, opts)
|
|
111
|
+
resource = client.resources.get_by_id(item.id, apiversion)
|
|
112
|
+
|
|
113
|
+
# parse the resource
|
|
114
|
+
parse_resource(resource)
|
|
115
|
+
end.compact
|
|
116
|
+
|
|
117
|
+
# Iterate around the counts and create the necessary classes
|
|
118
|
+
counts.each do |namespace, ns_counts|
|
|
119
|
+
define_singleton_method namespace do
|
|
120
|
+
AzureResourceTypeCounts.new(ns_counts)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Does the resource have any tags?
|
|
127
|
+
#
|
|
128
|
+
# If it is a Hashtable then it does not, because there was nothing to parse so there is not
|
|
129
|
+
# a nested object to work with
|
|
130
|
+
#
|
|
131
|
+
# @author Russell Seymour
|
|
132
|
+
def has_tags?
|
|
133
|
+
tags.is_a?(Hash) ? false : true
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns how many tags have been set on the resource
|
|
137
|
+
#
|
|
138
|
+
# @author Russell Seymour
|
|
139
|
+
def tag_count
|
|
140
|
+
tags.count
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# It is necessary to be able to test the tags of a resource. It is possible to say of the
|
|
144
|
+
# resource has tags or not, and it is possible to check that the tags include a specific tag
|
|
145
|
+
# However the value is not accessible, this function creates methods for all the tags that
|
|
146
|
+
# are available.
|
|
147
|
+
#
|
|
148
|
+
# The format of the method name is '<TAG_NAME>_tag' and will return the value of that tag
|
|
149
|
+
#
|
|
150
|
+
# Disabling rubopcop check. If this is set as a normal if..then..end statement there is a
|
|
151
|
+
# violation stating it should use a guard. When using a guard it throws this error
|
|
152
|
+
#
|
|
153
|
+
# @author Russell Seymour
|
|
154
|
+
def create_tag_methods
|
|
155
|
+
# Iterate around the items of the tags and create the necessary access methods
|
|
156
|
+
tags.item.each do |name, value|
|
|
157
|
+
method_name = format('%s_tag', name)
|
|
158
|
+
define_singleton_method method_name do
|
|
159
|
+
value
|
|
160
|
+
end
|
|
161
|
+
end if defined?(tags.item)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
# Filter the resources that are returned by the options that have been specified
|
|
167
|
+
#
|
|
168
|
+
def filter_resources(resources, opts)
|
|
169
|
+
if opts[:type] && opts[:name]
|
|
170
|
+
resources.select { |r| r.type == opts[:type] && r.name == opts[:name] }
|
|
171
|
+
elsif opts[:type]
|
|
172
|
+
resources.select { |r| r.type == opts[:type] }
|
|
173
|
+
elsif opts[:name]
|
|
174
|
+
resources.select { |r| r.name == opts[:name] }
|
|
175
|
+
else
|
|
176
|
+
resources
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Class to create methods on the calling object at run time.
|
|
183
|
+
# Each of the Azure Resources have different attributes and properties, and they all need
|
|
184
|
+
# to be testable. To do this no methods are hardcoded, each on is craeted based on the
|
|
185
|
+
# information returned from Azure.
|
|
186
|
+
#
|
|
187
|
+
# The class is a helper class essentially as it creates the methods on the calling class
|
|
188
|
+
# rather than itself. This means that there is less duplication of code and it can be
|
|
189
|
+
# reused easily.
|
|
190
|
+
#
|
|
191
|
+
# @author Russell Seymour
|
|
192
|
+
# @since 0.2.0
|
|
193
|
+
class AzureResourceDynamicMethods
|
|
194
|
+
# Given the calling object and its data, create the methods on the object according
|
|
195
|
+
# to the data that has been retrieved. Various types of data can be returned so the method
|
|
196
|
+
# checks the type to ensure that the necessary methods are configured correctly
|
|
197
|
+
#
|
|
198
|
+
# @param AzureResourceProbe|AzureResource object The object on which the methods should be craeted
|
|
199
|
+
# @param variant data The data from which the methods should be created
|
|
200
|
+
def create_methods(object, data)
|
|
201
|
+
# Check the type of data as this affects the setup of the methods
|
|
202
|
+
# If it is an Azure Generic Resource then setup methods for each of
|
|
203
|
+
# the instance variables
|
|
204
|
+
case data.class.to_s
|
|
205
|
+
when /^Azure::Resources::Mgmt::.*::Models::GenericResource$/,
|
|
206
|
+
/^Azure::Resources::Mgmt::.*::Models::ResourceGroup$/
|
|
207
|
+
# iterate around the instance variables
|
|
208
|
+
data.instance_variables.each do |var|
|
|
209
|
+
create_method(object, var.to_s.delete('@'), data.instance_variable_get(var))
|
|
210
|
+
end
|
|
211
|
+
# When the data is a Hash object iterate around each of the key value pairs and
|
|
212
|
+
# craete a method for each one.
|
|
213
|
+
when 'Hash'
|
|
214
|
+
data.each do |key, value|
|
|
215
|
+
create_method(object, key, value)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
private
|
|
221
|
+
|
|
222
|
+
# Method that is responsible for creating the method on the calling object. This is
|
|
223
|
+
# because some nesting maybe required. For example of the value is a Hash then it will
|
|
224
|
+
# need to have an AzureResourceProbe create for each key, whereas if it is a simple
|
|
225
|
+
# string then the value just needs to be returned
|
|
226
|
+
#
|
|
227
|
+
# @private
|
|
228
|
+
#
|
|
229
|
+
# @param AzureResourceProbe|AzureResource object Object on which the methods need to be created
|
|
230
|
+
# @param string name The name of the method
|
|
231
|
+
# @param variant value The value that needs to be returned by the method
|
|
232
|
+
def create_method(object, name, value)
|
|
233
|
+
# Create the necessary method based on the var that has been passed
|
|
234
|
+
# Test the value for its type so that the method can be setup correctly
|
|
235
|
+
case value.class.to_s
|
|
236
|
+
when 'String', 'Integer', 'TrueClass', 'FalseClass', 'Fixnum'
|
|
237
|
+
object.define_singleton_method name do
|
|
238
|
+
value
|
|
239
|
+
end
|
|
240
|
+
when 'Hash'
|
|
241
|
+
value.count.zero? ? return_value = value : return_value = AzureResourceProbe.new(value)
|
|
242
|
+
object.define_singleton_method name do
|
|
243
|
+
return_value
|
|
244
|
+
end
|
|
245
|
+
when /^Azure::Resources::Mgmt::.*::Models::ResourceGroupProperties$/
|
|
246
|
+
# This is a special case where the properties of the resource group is not a simple JSON model
|
|
247
|
+
# This is because the plugin is using the Azure SDK to get this information so it is an SDK object
|
|
248
|
+
# that has to be interrogated in a different way. This is the only object type that behaves like this
|
|
249
|
+
value.instance_variables.each do |var|
|
|
250
|
+
create_method(object, var.to_s.delete('@'), value.instance_variable_get(var))
|
|
251
|
+
end
|
|
252
|
+
when 'Array'
|
|
253
|
+
# Some things are just string or integer arrays
|
|
254
|
+
# Check this by seeing if the first element is a string / integer / boolean or
|
|
255
|
+
# a hashtable
|
|
256
|
+
# This may not be the best methid, but short of testing all elements in the array, this is
|
|
257
|
+
# the quickest test
|
|
258
|
+
case value[0].class.to_s
|
|
259
|
+
when 'String', 'Integer', 'TrueClass', 'FalseClass', 'Fixnum'
|
|
260
|
+
probes = value
|
|
261
|
+
else
|
|
262
|
+
probes = []
|
|
263
|
+
value.each do |value_item|
|
|
264
|
+
probes << AzureResourceProbe.new(value_item)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
object.define_singleton_method name do
|
|
268
|
+
probes
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Class object to maintain a count of the Azure Resource types that are found
|
|
275
|
+
# when a less specific test is carried out. For example if all the resoures of a resource
|
|
276
|
+
# group are called for, there will be variaous types and number of those types.
|
|
277
|
+
#
|
|
278
|
+
# Each type is namespaced, so for example a virtual machine has the type 'Microsoft.Compute/virtualMachines'
|
|
279
|
+
# This is broken down into the 'Microsoft' class with the type 'Compute/virtualMachines'
|
|
280
|
+
# This has been done for two reasons:
|
|
281
|
+
# 1. Enable the dotted notation to work in the test
|
|
282
|
+
# 2. Allow third party resource types ot be catered for if they are ever enabled by Microsoft
|
|
283
|
+
#
|
|
284
|
+
# @author Russell Seymour
|
|
285
|
+
# @since 0.2.0
|
|
286
|
+
class AzureResourceTypeCounts
|
|
287
|
+
# Constructor to setup a new class for a specific Azure Resource type.
|
|
288
|
+
# It should be passed a hashtable with information such as:
|
|
289
|
+
# {
|
|
290
|
+
# "Compute/virtualMachines" => 2,
|
|
291
|
+
# "Network/networkInterfaces" => 3
|
|
292
|
+
# }
|
|
293
|
+
# This will result in two methods being created on the class:
|
|
294
|
+
# - Compute/virtualNetworks
|
|
295
|
+
# - Network/networkInterfaces
|
|
296
|
+
# Each of which will return the corresponding count value
|
|
297
|
+
#
|
|
298
|
+
# @param Hash counts Hash table of types and the count of each one
|
|
299
|
+
#
|
|
300
|
+
# @return AzureResourceTypeCounts
|
|
301
|
+
def initialize(counts)
|
|
302
|
+
counts.each do |type, count|
|
|
303
|
+
define_singleton_method type do
|
|
304
|
+
count
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Class object that is created for each element that is returned by Azure.
|
|
311
|
+
# This is what is interogated by Inspec. If they are nested hashes, then this results
|
|
312
|
+
# in nested AzureResourceProbe objects.
|
|
313
|
+
#
|
|
314
|
+
# For example, if the following was seen in an Azure Resource
|
|
315
|
+
# properties -> storageProfile -> imageReference
|
|
316
|
+
# Would result in the following nestec classes
|
|
317
|
+
# AzureResource -> AzureResourceProbe -> AzureResourceProbe
|
|
318
|
+
#
|
|
319
|
+
# The methods for each of the classes are dynamically defined at run time and will
|
|
320
|
+
# match the items that are retrieved from Azure. See the 'test/integration/verify/controls' for
|
|
321
|
+
# examples
|
|
322
|
+
#
|
|
323
|
+
# This class will not be called externally
|
|
324
|
+
#
|
|
325
|
+
# @author Russell Seymour
|
|
326
|
+
# @since 0.2.0
|
|
327
|
+
# @attr_reader string name Name of the Azure resource
|
|
328
|
+
# @attr_reader string type Type of the Azure Resource
|
|
329
|
+
# @attr_reader string location Location in Azure of the resource
|
|
330
|
+
class AzureResourceProbe
|
|
331
|
+
attr_reader :name, :type, :location, :item, :count
|
|
332
|
+
|
|
333
|
+
# Initialize method for the class. Accepts an item, be it a scalar value, hash or Azure object
|
|
334
|
+
# It will then create the necessary dynamic methods so that they can be called in the tests
|
|
335
|
+
# This is accomplished by call the AzureResourceDynamicMethods
|
|
336
|
+
#
|
|
337
|
+
# @param varaint The item from which the class will be initialized
|
|
338
|
+
#
|
|
339
|
+
# @return AzureResourceProbe
|
|
340
|
+
def initialize(item)
|
|
341
|
+
dm = AzureResourceDynamicMethods.new
|
|
342
|
+
dm.create_methods(self, item)
|
|
343
|
+
|
|
344
|
+
# Set the item as a property on the class
|
|
345
|
+
# This is so that it is possible to interrogate what has been added to the class and isolate them from
|
|
346
|
+
# the standard methods that a Ruby class has.
|
|
347
|
+
# This used for checking Tags on a resource for example
|
|
348
|
+
# It also allows direct access if so required
|
|
349
|
+
@item = item
|
|
350
|
+
|
|
351
|
+
# Set how many items have been set
|
|
352
|
+
@count = item.length
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
# Allows resources to respond to the include test
|
|
356
|
+
# This means that things like tags can be checked for and then their value tested
|
|
357
|
+
#
|
|
358
|
+
# @author Russell Seymour
|
|
359
|
+
#
|
|
360
|
+
# @param [String] key Name of the item to look for in the @item property
|
|
361
|
+
def include?(key)
|
|
362
|
+
@item.key?(key)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Give a sting like `computer_name` return the camelCase version, e.g.
|
|
366
|
+
# computerName
|
|
367
|
+
#
|
|
368
|
+
# @param string data Data that needs to be converted from snake_case to camelCase
|
|
369
|
+
#
|
|
370
|
+
# @return string
|
|
371
|
+
def camel_case(data)
|
|
372
|
+
camel_case_data = data.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
|
373
|
+
|
|
374
|
+
# Ensure that gb (as in gigabytes) is uppercased
|
|
375
|
+
camel_case_data.gsub(/[gb]/, &:upcase)
|
|
376
|
+
end
|
|
377
|
+
end
|