puppet 6.12.0-universal-darwin → 6.17.0-universal-darwin
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CODEOWNERS +2 -7
- data/CONTRIBUTING.md +7 -13
- data/Gemfile +4 -2
- data/Gemfile.lock +39 -36
- data/README.md +18 -25
- data/ext/project_data.yaml +1 -1
- data/ext/windows/service/daemon.rb +3 -3
- data/lib/puppet.rb +52 -13
- data/lib/puppet/agent.rb +20 -14
- data/lib/puppet/application/agent.rb +26 -17
- data/lib/puppet/application/describe.rb +7 -5
- data/lib/puppet/application/device.rb +2 -2
- data/lib/puppet/application/filebucket.rb +19 -15
- data/lib/puppet/application/plugin.rb +1 -0
- data/lib/puppet/application/resource.rb +1 -1
- data/lib/puppet/application/ssl.rb +4 -4
- data/lib/puppet/configurer.rb +65 -69
- data/lib/puppet/configurer/plugin_handler.rb +10 -1
- data/lib/puppet/confine.rb +1 -1
- data/lib/puppet/context/trusted_information.rb +14 -8
- data/lib/puppet/daemon.rb +13 -27
- data/lib/puppet/defaults.rb +154 -58
- data/lib/puppet/environments.rb +27 -20
- data/lib/puppet/face/facts.rb +8 -5
- data/lib/puppet/face/help.rb +29 -3
- data/lib/puppet/face/module/search.rb +5 -0
- data/lib/puppet/face/plugin.rb +2 -2
- data/lib/puppet/file_serving/http_metadata.rb +14 -2
- data/lib/puppet/file_serving/metadata.rb +4 -1
- data/lib/puppet/file_serving/terminus_selector.rb +7 -8
- data/lib/puppet/file_system/file_impl.rb +14 -10
- data/lib/puppet/file_system/memory_file.rb +6 -0
- data/lib/puppet/file_system/memory_impl.rb +13 -0
- data/lib/puppet/file_system/uniquefile.rb +12 -16
- data/lib/puppet/file_system/windows.rb +7 -10
- data/lib/puppet/forge.rb +1 -1
- data/lib/puppet/forge/cache.rb +1 -1
- data/lib/puppet/forge/repository.rb +4 -7
- data/lib/puppet/functions/call.rb +1 -1
- data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
- data/lib/puppet/functions/filter.rb +1 -0
- data/lib/puppet/functions/reduce.rb +2 -4
- data/lib/puppet/http.rb +5 -0
- data/lib/puppet/http/client.rb +293 -73
- data/lib/puppet/http/errors.rb +2 -0
- data/lib/puppet/http/external_client.rb +90 -0
- data/lib/puppet/http/redirector.rb +43 -7
- data/lib/puppet/http/resolver.rb +46 -3
- data/lib/puppet/http/resolver/server_list.rb +76 -16
- data/lib/puppet/http/resolver/settings.rb +23 -3
- data/lib/puppet/http/resolver/srv.rb +29 -3
- data/lib/puppet/http/response.rb +87 -1
- data/lib/puppet/http/retry_after_handler.rb +39 -0
- data/lib/puppet/http/service.rb +151 -7
- data/lib/puppet/http/service/ca.rb +76 -14
- data/lib/puppet/http/service/compiler.rb +319 -0
- data/lib/puppet/http/service/file_server.rb +206 -0
- data/lib/puppet/http/service/report.rb +49 -23
- data/lib/puppet/http/session.rb +103 -7
- data/lib/puppet/indirector.rb +1 -1
- data/lib/puppet/indirector/catalog/compiler.rb +10 -0
- data/lib/puppet/indirector/catalog/rest.rb +34 -0
- data/lib/puppet/indirector/facts/rest.rb +42 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
- data/lib/puppet/indirector/file_content/http.rb +5 -0
- data/lib/puppet/indirector/file_content/rest.rb +30 -0
- data/lib/puppet/indirector/file_metadata/http.rb +27 -8
- data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
- data/lib/puppet/indirector/json.rb +1 -1
- data/lib/puppet/indirector/msgpack.rb +1 -1
- data/lib/puppet/indirector/node/rest.rb +24 -0
- data/lib/puppet/indirector/report/rest.rb +19 -0
- data/lib/puppet/indirector/report/yaml.rb +23 -0
- data/lib/puppet/indirector/request.rb +1 -1
- data/lib/puppet/indirector/rest.rb +12 -0
- data/lib/puppet/indirector/status/rest.rb +18 -0
- data/lib/puppet/loaders.rb +6 -0
- data/lib/puppet/metatype/manager.rb +80 -80
- data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
- data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
- data/lib/puppet/network/http/base_pool.rb +7 -2
- data/lib/puppet/network/http/compression.rb +7 -0
- data/lib/puppet/network/http/connection.rb +6 -0
- data/lib/puppet/network/http/connection_adapter.rb +184 -0
- data/lib/puppet/network/http/nocache_pool.rb +2 -0
- data/lib/puppet/network/http/pool.rb +13 -6
- data/lib/puppet/network/http_pool.rb +2 -1
- data/lib/puppet/node/environment.rb +11 -1
- data/lib/puppet/pal/catalog_compiler.rb +5 -0
- data/lib/puppet/pal/pal_impl.rb +4 -29
- data/lib/puppet/parser/ast/leaf.rb +5 -5
- data/lib/puppet/parser/ast/pops_bridge.rb +6 -15
- data/lib/puppet/parser/compiler.rb +43 -33
- data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
- data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
- data/lib/puppet/parser/environment_compiler.rb +4 -1
- data/lib/puppet/parser/functions.rb +18 -13
- data/lib/puppet/parser/functions/filter.rb +1 -0
- data/lib/puppet/parser/resource.rb +3 -2
- data/lib/puppet/parser/resource/param.rb +6 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +6 -6
- data/lib/puppet/pops/issues.rb +5 -0
- data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
- data/lib/puppet/pops/loaders.rb +7 -5
- data/lib/puppet/pops/parser/evaluating_parser.rb +5 -7
- data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
- data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
- data/lib/puppet/pops/types/type_calculator.rb +24 -0
- data/lib/puppet/pops/validation/checker4_0.rb +11 -1
- data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/provider/aix_object.rb +4 -2
- data/lib/puppet/provider/group/aix.rb +1 -0
- data/lib/puppet/provider/group/groupadd.rb +57 -24
- data/lib/puppet/provider/group/windows_adsi.rb +3 -3
- data/lib/puppet/provider/package/aix.rb +17 -2
- data/lib/puppet/provider/package/apt.rb +78 -4
- data/lib/puppet/provider/package/aptitude.rb +1 -1
- data/lib/puppet/provider/package/dnfmodule.rb +69 -15
- data/lib/puppet/provider/package/dpkg.rb +14 -7
- data/lib/puppet/provider/package/fink.rb +20 -3
- data/lib/puppet/provider/package/gem.rb +41 -7
- data/lib/puppet/provider/package/openbsd.rb +13 -1
- data/lib/puppet/provider/package/pacman.rb +2 -5
- data/lib/puppet/provider/package/pip.rb +143 -48
- data/lib/puppet/provider/package/pip3.rb +0 -2
- data/lib/puppet/provider/package/pkg.rb +18 -5
- data/lib/puppet/provider/package/pkgdmg.rb +1 -1
- data/lib/puppet/provider/package/pkgng.rb +16 -4
- data/lib/puppet/provider/package/portage.rb +2 -2
- data/lib/puppet/provider/package/puppet_gem.rb +6 -2
- data/lib/puppet/provider/package/rpm.rb +6 -213
- data/lib/puppet/provider/package/yum.rb +109 -25
- data/lib/puppet/provider/package/zypper.rb +59 -1
- data/lib/puppet/provider/service/systemd.rb +22 -4
- data/lib/puppet/provider/service/windows.rb +23 -7
- data/lib/puppet/provider/user/aix.rb +1 -0
- data/lib/puppet/provider/user/directoryservice.rb +30 -5
- data/lib/puppet/provider/user/useradd.rb +22 -12
- data/lib/puppet/reports/http.rb +15 -9
- data/lib/puppet/reports/store.rb +1 -1
- data/lib/puppet/resource.rb +2 -1
- data/lib/puppet/resource/type.rb +8 -0
- data/lib/puppet/resource/type_collection.rb +20 -16
- data/lib/puppet/runtime.rb +31 -1
- data/lib/puppet/settings.rb +4 -0
- data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
- data/lib/puppet/ssl.rb +1 -0
- data/lib/puppet/ssl/certificate.rb +2 -1
- data/lib/puppet/ssl/host.rb +4 -4
- data/lib/puppet/ssl/oids.rb +1 -0
- data/lib/puppet/ssl/ssl_context.rb +2 -2
- data/lib/puppet/ssl/ssl_provider.rb +20 -1
- data/lib/puppet/ssl/state_machine.rb +81 -35
- data/lib/puppet/ssl/verifier_adapter.rb +9 -1
- data/lib/puppet/test/test_helper.rb +15 -11
- data/lib/puppet/transaction/report.rb +2 -2
- data/lib/puppet/transaction/resource_harness.rb +1 -1
- data/lib/puppet/trusted_external.rb +29 -1
- data/lib/puppet/type.rb +18 -6
- data/lib/puppet/type/file.rb +51 -13
- data/lib/puppet/type/file/checksum.rb +4 -4
- data/lib/puppet/type/file/source.rb +51 -60
- data/lib/puppet/type/group.rb +2 -2
- data/lib/puppet/type/package.rb +102 -10
- data/lib/puppet/type/service.rb +55 -8
- data/lib/puppet/type/user.rb +3 -28
- data/lib/puppet/util.rb +39 -15
- data/lib/puppet/util/at_fork.rb +1 -1
- data/lib/puppet/util/autoload.rb +4 -18
- data/lib/puppet/util/checksums.rb +19 -4
- data/lib/puppet/util/fileparsing.rb +2 -2
- data/lib/puppet/util/instance_loader.rb +14 -10
- data/lib/puppet/util/log/destinations.rb +2 -11
- data/lib/puppet/util/package/version/debian.rb +175 -0
- data/lib/puppet/util/package/version/gem.rb +15 -0
- data/lib/puppet/util/package/version/pip.rb +167 -0
- data/lib/puppet/util/package/version/range.rb +53 -0
- data/lib/puppet/util/package/version/range/eq.rb +14 -0
- data/lib/puppet/util/package/version/range/gt.rb +14 -0
- data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
- data/lib/puppet/util/package/version/range/lt.rb +14 -0
- data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
- data/lib/puppet/util/package/version/range/min_max.rb +21 -0
- data/lib/puppet/util/package/version/range/simple.rb +11 -0
- data/lib/puppet/util/package/version/rpm.rb +73 -0
- data/lib/puppet/util/pidlock.rb +36 -10
- data/lib/puppet/util/platform.rb +5 -0
- data/lib/puppet/util/plist.rb +6 -0
- data/lib/puppet/util/provider_features.rb +1 -1
- data/lib/puppet/util/reference.rb +1 -1
- data/lib/puppet/util/rpm_compare.rb +193 -0
- data/lib/puppet/util/storage.rb +0 -1
- data/lib/puppet/util/windows/adsi.rb +2 -2
- data/lib/puppet/util/windows/api_types.rb +45 -32
- data/lib/puppet/util/windows/eventlog.rb +1 -6
- data/lib/puppet/util/windows/principal.rb +8 -6
- data/lib/puppet/util/windows/process.rb +15 -14
- data/lib/puppet/util/windows/registry.rb +11 -11
- data/lib/puppet/util/windows/security.rb +1 -0
- data/lib/puppet/util/windows/service.rb +43 -26
- data/lib/puppet/util/windows/sid.rb +3 -3
- data/lib/puppet/util/windows/user.rb +23 -8
- data/lib/puppet/util/yaml.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +707 -574
- data/man/man5/puppet.conf.5 +74 -14
- data/man/man8/puppet-agent.8 +7 -7
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +2 -2
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +17 -2
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +6 -3
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +4 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +2 -2
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
- data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
- data/spec/fixtures/ssl/unknown-ca.pem +59 -0
- data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
- data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
- data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -102
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -106
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -106
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -102
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -98
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -102
- data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -102
- data/spec/integration/application/agent_spec.rb +483 -0
- data/spec/integration/application/apply_spec.rb +132 -3
- data/spec/integration/application/filebucket_spec.rb +190 -0
- data/spec/integration/application/plugin_spec.rb +73 -0
- data/spec/integration/configurer_spec.rb +26 -7
- data/spec/integration/defaults_spec.rb +1 -2
- data/spec/integration/http/client_spec.rb +47 -37
- data/spec/integration/indirector/facts/facter_spec.rb +4 -0
- data/spec/integration/indirector/report/yaml.rb +83 -0
- data/spec/integration/module_tool/forge_spec.rb +2 -15
- data/spec/integration/network/http_pool_spec.rb +93 -20
- data/spec/integration/node/environment_spec.rb +15 -0
- data/spec/integration/parser/compiler_spec.rb +11 -0
- data/spec/integration/type/file_spec.rb +1 -1
- data/spec/integration/util/windows/adsi_spec.rb +6 -1
- data/spec/integration/util/windows/registry_spec.rb +7 -7
- data/spec/integration/util/windows/user_spec.rb +40 -5
- data/spec/lib/puppet/test_ca.rb +2 -2
- data/spec/lib/puppet_spec/https.rb +16 -7
- data/spec/lib/puppet_spec/puppetserver.rb +119 -0
- data/spec/shared_contexts/https.rb +29 -0
- data/spec/unit/agent_spec.rb +80 -26
- data/spec/unit/application/agent_spec.rb +9 -5
- data/spec/unit/application/apply_spec.rb +2 -12
- data/spec/unit/application/describe_spec.rb +88 -50
- data/spec/unit/application/device_spec.rb +2 -2
- data/spec/unit/application/filebucket_spec.rb +22 -2
- data/spec/unit/application/resource_spec.rb +2 -2
- data/spec/unit/configurer/fact_handler_spec.rb +4 -8
- data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
- data/spec/unit/configurer_spec.rb +17 -18
- data/spec/unit/context/trusted_information_spec.rb +25 -2
- data/spec/unit/daemon_spec.rb +5 -64
- data/spec/unit/defaults_spec.rb +25 -2
- data/spec/unit/environments_spec.rb +65 -28
- data/spec/unit/face/facts_spec.rb +24 -20
- data/spec/unit/face/module/search_spec.rb +17 -0
- data/spec/unit/face/plugin_spec.rb +12 -10
- data/spec/unit/file_serving/http_metadata_spec.rb +37 -14
- data/spec/unit/file_serving/terminus_selector_spec.rb +45 -26
- data/spec/unit/file_system/uniquefile_spec.rb +11 -0
- data/spec/unit/file_system_spec.rb +26 -2
- data/spec/unit/functions/lookup_spec.rb +13 -0
- data/spec/unit/http/client_spec.rb +327 -35
- data/spec/unit/http/external_client_spec.rb +201 -0
- data/spec/unit/http/resolver_spec.rb +34 -2
- data/spec/unit/http/response_spec.rb +75 -0
- data/spec/unit/http/service/ca_spec.rb +53 -11
- data/spec/unit/http/service/compiler_spec.rb +627 -0
- data/spec/unit/http/service/file_server_spec.rb +308 -0
- data/spec/unit/http/service/report_spec.rb +27 -9
- data/spec/unit/http/service_spec.rb +98 -5
- data/spec/unit/http/session_spec.rb +190 -7
- data/spec/unit/indirector/catalog/compiler_spec.rb +47 -29
- data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
- data/spec/unit/indirector/facts/rest_spec.rb +79 -24
- data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
- data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
- data/spec/unit/indirector/file_metadata/http_spec.rb +194 -0
- data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
- data/spec/unit/indirector/node/rest_spec.rb +57 -2
- data/spec/unit/indirector/report/rest_spec.rb +58 -51
- data/spec/unit/indirector/request_spec.rb +1 -1
- data/spec/unit/indirector/resource/ral_spec.rb +7 -8
- data/spec/unit/indirector/rest_spec.rb +13 -0
- data/spec/unit/indirector/status/rest_spec.rb +43 -2
- data/spec/unit/interface_spec.rb +3 -3
- data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
- data/spec/unit/network/http/connection_spec.rb +559 -175
- data/spec/unit/network/http/nocache_pool_spec.rb +25 -3
- data/spec/unit/network/http/pool_spec.rb +89 -11
- data/spec/unit/network/http_pool_spec.rb +63 -57
- data/spec/unit/network/http_spec.rb +1 -1
- data/spec/unit/node/environment_spec.rb +16 -0
- data/spec/unit/node/facts_spec.rb +2 -1
- data/spec/unit/node_spec.rb +7 -4
- data/spec/unit/parser/ast/block_expression_spec.rb +1 -1
- data/spec/unit/parser/environment_compiler_spec.rb +7 -0
- data/spec/unit/parser/scope_spec.rb +1 -1
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +15 -1
- data/spec/unit/pops/loaders/loaders_spec.rb +1 -1
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
- data/spec/unit/pops/types/type_calculator_spec.rb +1 -11
- data/spec/unit/pops/validator/validator_spec.rb +7 -2
- data/spec/unit/provider/aix_object_spec.rb +16 -2
- data/spec/unit/provider/group/groupadd_spec.rb +181 -56
- data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
- data/spec/unit/provider/package/aix_spec.rb +29 -0
- data/spec/unit/provider/package/apt_spec.rb +43 -2
- data/spec/unit/provider/package/aptitude_spec.rb +1 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +76 -15
- data/spec/unit/provider/package/dpkg_spec.rb +28 -6
- data/spec/unit/provider/package/gem_spec.rb +40 -0
- data/spec/unit/provider/package/openbsd_spec.rb +17 -0
- data/spec/unit/provider/package/pacman_spec.rb +6 -21
- data/spec/unit/provider/package/pip_spec.rb +68 -19
- data/spec/unit/provider/package/pkg_spec.rb +15 -1
- data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
- data/spec/unit/provider/package/pkgng_spec.rb +38 -0
- data/spec/unit/provider/package/portage_spec.rb +5 -0
- data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
- data/spec/unit/provider/package/rpm_spec.rb +0 -212
- data/spec/unit/provider/package/yum_spec.rb +292 -0
- data/spec/unit/provider/package/zypper_spec.rb +84 -0
- data/spec/unit/provider/service/init_spec.rb +1 -0
- data/spec/unit/provider/service/openbsd_spec.rb +9 -0
- data/spec/unit/provider/service/openwrt_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +9 -0
- data/spec/unit/provider/service/systemd_spec.rb +92 -12
- data/spec/unit/provider/service/windows_spec.rb +22 -14
- data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
- data/spec/unit/provider/user/openbsd_spec.rb +1 -0
- data/spec/unit/provider/user/useradd_spec.rb +43 -24
- data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
- data/spec/unit/puppet_pal_2pec.rb +0 -26
- data/spec/unit/puppet_pal_catalog_spec.rb +46 -0
- data/spec/unit/puppet_spec.rb +47 -0
- data/spec/unit/reports/http_spec.rb +70 -52
- data/spec/unit/resource_spec.rb +3 -3
- data/spec/unit/settings/autosign_setting_spec.rb +1 -1
- data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
- data/spec/unit/ssl/certificate_spec.rb +7 -0
- data/spec/unit/ssl/host_spec.rb +4 -2
- data/spec/unit/ssl/oids_spec.rb +1 -0
- data/spec/unit/ssl/ssl_provider_spec.rb +69 -43
- data/spec/unit/ssl/state_machine_spec.rb +99 -13
- data/spec/unit/test/test_helper_spec.rb +17 -0
- data/spec/unit/transaction/persistence_spec.rb +1 -10
- data/spec/unit/transaction/report_spec.rb +5 -1
- data/spec/unit/transaction_spec.rb +0 -2
- data/spec/unit/type/file/ensure_spec.rb +1 -2
- data/spec/unit/type/file/source_spec.rb +89 -38
- data/spec/unit/type/file_spec.rb +122 -96
- data/spec/unit/type/package_spec.rb +8 -0
- data/spec/unit/type/service_spec.rb +185 -8
- data/spec/unit/type/user_spec.rb +1 -2
- data/spec/unit/type_spec.rb +50 -0
- data/spec/unit/util/at_fork_spec.rb +3 -2
- data/spec/unit/util/autoload_spec.rb +2 -1
- data/spec/unit/util/checksums_spec.rb +16 -0
- data/spec/unit/util/log/destinations_spec.rb +1 -29
- data/spec/unit/util/package/version/debian_spec.rb +83 -0
- data/spec/unit/util/package/version/pip_spec.rb +464 -0
- data/spec/unit/util/package/version/range_spec.rb +175 -0
- data/spec/unit/util/package/version/rpm_spec.rb +121 -0
- data/spec/unit/util/pidlock_spec.rb +112 -42
- data/spec/unit/util/plist_spec.rb +20 -0
- data/spec/unit/util/rpm_compare_spec.rb +196 -0
- data/spec/unit/util/storage_spec.rb +1 -8
- data/spec/unit/util/windows/adsi_spec.rb +4 -4
- data/spec/unit/util/windows/api_types_spec.rb +104 -40
- data/spec/unit/util/windows/service_spec.rb +4 -4
- data/spec/unit/util/windows/sid_spec.rb +2 -2
- data/spec/unit/util_spec.rb +3 -3
- data/spec/unit/x509/cert_provider_spec.rb +1 -1
- data/tasks/generate_cert_fixtures.rake +15 -1
- data/tasks/manpages.rake +5 -35
- metadata +73 -12
- data/COMMITTERS.md +0 -244
- data/spec/integration/faces/plugin_spec.rb +0 -61
- data/spec/integration/test/test_helper_spec.rb +0 -31
@@ -211,4 +211,21 @@ describe "puppet module search" do
|
|
211
211
|
end
|
212
212
|
end
|
213
213
|
end
|
214
|
+
|
215
|
+
it "should include a deprecation warning" do
|
216
|
+
stub_request(:get, "https://forgeapi.puppet.com/v3/modules?query=puppetlabs-apache").to_return(status: 200, body: [answers: [], result: :success])
|
217
|
+
|
218
|
+
subject.search("puppetlabs-apache")
|
219
|
+
|
220
|
+
expect(@logs).to include(an_object_having_attributes(level: :warning, message: /This action has been deprecated. Please use the Puppet Forge to search for modules./))
|
221
|
+
end
|
222
|
+
|
223
|
+
it "omits the warning when deprecations are disabled" do
|
224
|
+
stub_request(:get, "https://forgeapi.puppet.com/v3/modules?query=puppetlabs-apache").to_return(status: 200, body: [answers: [], result: :success])
|
225
|
+
|
226
|
+
Puppet[:disable_warnings] = 'deprecations'
|
227
|
+
subject.search("puppetlabs-apache")
|
228
|
+
|
229
|
+
expect(@logs).not_to include(an_object_having_attributes(level: :warning))
|
230
|
+
end
|
214
231
|
end
|
@@ -10,9 +10,10 @@ describe Puppet::Face[:plugin, :current] do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
context "download" do
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
around do |example|
|
14
|
+
Puppet.override(server_agent_version: "5.3.4") do
|
15
|
+
example.run
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
19
|
it "downloads plugins, external facts, and locales" do
|
@@ -61,9 +62,10 @@ describe Puppet::Face[:plugin, :current] do
|
|
61
62
|
end
|
62
63
|
|
63
64
|
context "download when server_agent_version is 5.3.3" do
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
around do |example|
|
66
|
+
Puppet.override(server_agent_version: "5.3.3") do
|
67
|
+
example.run
|
68
|
+
end
|
67
69
|
end
|
68
70
|
|
69
71
|
it "downloads plugins, and external facts, but not locales" do
|
@@ -87,10 +89,10 @@ describe Puppet::Face[:plugin, :current] do
|
|
87
89
|
end
|
88
90
|
|
89
91
|
context "download when server_agent_version is blank" do
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
around do |example|
|
93
|
+
Puppet.override(server_agent_version: "") do
|
94
|
+
example.run
|
95
|
+
end
|
94
96
|
end
|
95
97
|
|
96
98
|
it "downloads plugins, and external facts, but not locales" do
|
@@ -30,11 +30,6 @@ describe Puppet::FileServing::HttpMetadata do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
context "with no Last-Modified or Content-MD5 header from the server" do
|
33
|
-
before do
|
34
|
-
allow(http_response).to receive(:[]).with('last-modified').and_return(nil)
|
35
|
-
allow(http_response).to receive(:[]).with('content-md5').and_return(nil)
|
36
|
-
end
|
37
|
-
|
38
33
|
it "should use :mtime as the checksum type, based on current time" do
|
39
34
|
# Stringifying Time.now does some rounding; do so here so we don't end up with a time
|
40
35
|
# that's greater than the stringified version returned by collect.
|
@@ -51,13 +46,9 @@ describe Puppet::FileServing::HttpMetadata do
|
|
51
46
|
context "with a Last-Modified header from the server" do
|
52
47
|
let(:time) { Time.now.utc }
|
53
48
|
|
54
|
-
before do
|
55
|
-
allow(http_response).to receive(:[]).with('content-md5').and_return(nil)
|
56
|
-
end
|
57
|
-
|
58
49
|
it "should use :mtime as the checksum type, based on Last-Modified" do
|
59
50
|
# HTTP uses "GMT" not "UTC"
|
60
|
-
|
51
|
+
http_response.add_field('last-modified', time.strftime("%a, %d %b %Y %T GMT"))
|
61
52
|
metadata = described_class.new(http_response)
|
62
53
|
metadata.collect
|
63
54
|
expect( metadata.checksum_type ).to eq :mtime
|
@@ -70,16 +61,48 @@ describe Puppet::FileServing::HttpMetadata do
|
|
70
61
|
let(:base64) { Digest::MD5.new.base64digest input }
|
71
62
|
let(:hex) { Digest::MD5.new.hexdigest input }
|
72
63
|
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
it "should use the md5 checksum" do
|
65
|
+
http_response.add_field('content-md5', base64)
|
66
|
+
metadata = described_class.new(http_response)
|
67
|
+
metadata.collect
|
68
|
+
expect( metadata.checksum_type ).to eq :md5
|
69
|
+
expect( metadata.checksum ).to eq "{md5}#{hex}"
|
76
70
|
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with X-Checksum-Md5" do
|
74
|
+
let(:md5) { "c58989e9740a748de4f5054286faf99b" }
|
77
75
|
|
78
76
|
it "should use the md5 checksum" do
|
77
|
+
http_response.add_field('X-Checksum-Md5', md5)
|
79
78
|
metadata = described_class.new(http_response)
|
80
79
|
metadata.collect
|
81
80
|
expect( metadata.checksum_type ).to eq :md5
|
82
|
-
expect( metadata.checksum ).to eq "{md5}#{
|
81
|
+
expect( metadata.checksum ).to eq "{md5}#{md5}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with X-Checksum-Sha1" do
|
86
|
+
let(:sha1) { "01e4d15746f4274b84d740a93e04b9fd2882e3ea" }
|
87
|
+
|
88
|
+
it "should use the SHA1 checksum" do
|
89
|
+
http_response.add_field('X-Checksum-Sha1', sha1)
|
90
|
+
metadata = described_class.new(http_response)
|
91
|
+
metadata.collect
|
92
|
+
expect( metadata.checksum_type ).to eq :sha1
|
93
|
+
expect( metadata.checksum ).to eq "{sha1}#{sha1}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with X-Checksum-Sha256" do
|
98
|
+
let(:sha256) { "a3eda98259c30e1e75039c2123670c18105e1c46efb672e42ca0e4cbe77b002a" }
|
99
|
+
|
100
|
+
it "should use the SHA256 checksum" do
|
101
|
+
http_response.add_field('X-Checksum-Sha256', sha256)
|
102
|
+
metadata = described_class.new(http_response)
|
103
|
+
metadata.collect
|
104
|
+
expect( metadata.checksum_type ).to eq :sha256
|
105
|
+
expect( metadata.checksum ).to eq "{sha256}#{sha256}"
|
83
106
|
end
|
84
107
|
end
|
85
108
|
end
|
@@ -3,62 +3,81 @@ require 'spec_helper'
|
|
3
3
|
require 'puppet/file_serving/terminus_selector'
|
4
4
|
|
5
5
|
describe Puppet::FileServing::TerminusSelector do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class TestSelector
|
7
|
+
include Puppet::FileServing::TerminusSelector
|
8
|
+
end
|
9
9
|
|
10
|
-
|
10
|
+
def create_request(key)
|
11
|
+
Puppet::Indirector::Request.new(:indirection_name, :find, key, nil, {node: 'whatever'})
|
11
12
|
end
|
12
13
|
|
14
|
+
subject { TestSelector.new }
|
15
|
+
|
13
16
|
describe "when being used to select termini" do
|
14
17
|
it "should return :file if the request key is fully qualified" do
|
15
|
-
|
16
|
-
|
18
|
+
request = create_request(File.expand_path('/foo'))
|
19
|
+
|
20
|
+
expect(subject.select(request)).to eq(:file)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return :file_server if the request key is relative" do
|
24
|
+
request = create_request('modules/my_module/path/to_file')
|
25
|
+
|
26
|
+
expect(subject.select(request)).to eq(:file_server)
|
17
27
|
end
|
18
28
|
|
19
29
|
it "should return :file if the URI protocol is set to 'file'" do
|
20
|
-
|
21
|
-
|
30
|
+
request = create_request(Puppet::Util.path_to_uri(File.expand_path("/foo")).to_s)
|
31
|
+
|
32
|
+
expect(subject.select(request)).to eq(:file)
|
22
33
|
end
|
23
34
|
|
24
35
|
it "should return :http if the URI protocol is set to 'http'" do
|
25
|
-
|
26
|
-
|
36
|
+
request = create_request("http://www.example.com")
|
37
|
+
|
38
|
+
expect(subject.select(request)).to eq(:http)
|
27
39
|
end
|
28
40
|
|
29
41
|
it "should return :http if the URI protocol is set to 'https'" do
|
30
|
-
|
31
|
-
|
42
|
+
request = create_request("https://www.example.com")
|
43
|
+
|
44
|
+
expect(subject.select(request)).to eq(:http)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return :http if the path starts with a double slash" do
|
48
|
+
request = create_request("https://www.example.com//index.html")
|
49
|
+
|
50
|
+
expect(subject.select(request)).to eq(:http)
|
32
51
|
end
|
33
52
|
|
34
53
|
it "should fail when a protocol other than :puppet, :http(s) or :file is used" do
|
35
|
-
|
36
|
-
|
54
|
+
request = create_request("ftp://ftp.example.com")
|
55
|
+
|
56
|
+
expect {
|
57
|
+
subject.select(request)
|
58
|
+
}.to raise_error(ArgumentError, /URI protocol 'ftp' is not currently supported for file serving/)
|
37
59
|
end
|
38
60
|
|
39
61
|
describe "and the protocol is 'puppet'" do
|
40
|
-
before do
|
41
|
-
allow(@request).to receive(:protocol).and_return("puppet")
|
42
|
-
end
|
43
|
-
|
44
62
|
it "should choose :rest when a server is specified" do
|
45
|
-
|
46
|
-
|
47
|
-
expect(
|
63
|
+
request = create_request("puppet://puppetserver.example.com")
|
64
|
+
|
65
|
+
expect(subject.select(request)).to eq(:rest)
|
48
66
|
end
|
49
67
|
|
50
68
|
# This is so a given file location works when bootstrapping with no server.
|
51
69
|
it "should choose :rest when default_file_terminus is rest" do
|
52
|
-
allow(@request).to receive(:protocol).and_return("puppet")
|
53
70
|
Puppet[:server] = 'localhost'
|
54
|
-
|
71
|
+
request = create_request("puppet:///plugins")
|
72
|
+
|
73
|
+
expect(subject.select(request)).to eq(:rest)
|
55
74
|
end
|
56
75
|
|
57
76
|
it "should choose :file_server when default_file_terminus is file_server and no server is specified on the request" do
|
58
|
-
expect(@request).to receive(:protocol).and_return("puppet")
|
59
|
-
expect(@request).to receive(:server).and_return(nil)
|
60
77
|
Puppet[:default_file_terminus] = 'file_server'
|
61
|
-
|
78
|
+
request = create_request("puppet:///plugins")
|
79
|
+
|
80
|
+
expect(subject.select(request)).to eq(:file_server)
|
62
81
|
end
|
63
82
|
end
|
64
83
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Puppet::FileSystem::Uniquefile do
|
4
|
+
include PuppetSpec::Files
|
5
|
+
|
4
6
|
it "makes the name of the file available" do
|
5
7
|
Puppet::FileSystem::Uniquefile.open_tmp('foo') do |file|
|
6
8
|
expect(file.path).to match(/foo/)
|
@@ -73,6 +75,15 @@ describe Puppet::FileSystem::Uniquefile do
|
|
73
75
|
Puppet::FileSystem::Uniquefile.open_tmp('foo') { |tmp| }
|
74
76
|
end
|
75
77
|
|
78
|
+
it "reports when a parent directory does not exist" do
|
79
|
+
dir = tmpdir('uniquefile')
|
80
|
+
lock = File.join(dir, 'path', 'to', 'lock')
|
81
|
+
|
82
|
+
expect {
|
83
|
+
Puppet::FileSystem::Uniquefile.open_tmp(lock) { |tmp| }
|
84
|
+
}.to raise_error(Errno::ENOENT, %r{No such file or directory - A directory component in .* does not exist or is a dangling symbolic link})
|
85
|
+
end
|
86
|
+
|
76
87
|
context "Ruby 1.9.3 Tempfile tests" do
|
77
88
|
# the remaining tests in this file are ported directly from the ruby 1.9.3 source,
|
78
89
|
# since most of this file was ported from there
|
@@ -970,6 +970,16 @@ describe "Puppet::FileSystem" do
|
|
970
970
|
mode = Puppet::FileSystem.stat(dest).mode
|
971
971
|
expect(mode & 07777).to eq(0400)
|
972
972
|
end
|
973
|
+
|
974
|
+
it 'preserves file ownership' do
|
975
|
+
allow(Puppet::FileSystem).to receive(:lstat)
|
976
|
+
.with(Puppet::FileSystem.pathname(dest))
|
977
|
+
.and_return(double(uid: 1, gid: 2))
|
978
|
+
|
979
|
+
expect(FileUtils).to receive(:chown).with(1, 2, /#{dest}/)
|
980
|
+
|
981
|
+
Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
|
982
|
+
end
|
973
983
|
end
|
974
984
|
|
975
985
|
context 'on windows', if: Puppet::Util::Platform.windows? do
|
@@ -988,7 +998,7 @@ describe "Puppet::FileSystem" do
|
|
988
998
|
it 'rejects unsupported modes' do
|
989
999
|
expect {
|
990
1000
|
Puppet::FileSystem.replace_file(dest, 0755) { |_| }
|
991
|
-
}.to raise_error(ArgumentError, /Only modes 0644, 0640 and
|
1001
|
+
}.to raise_error(ArgumentError, /Only modes 0644, 0640, 0660, and 0440 are allowed/)
|
992
1002
|
end
|
993
1003
|
end
|
994
1004
|
end
|
@@ -1065,12 +1075,26 @@ describe "Puppet::FileSystem" do
|
|
1065
1075
|
end
|
1066
1076
|
end
|
1067
1077
|
|
1068
|
-
it 'applies
|
1078
|
+
it 'applies 0644 mode' do
|
1069
1079
|
Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
|
1070
1080
|
|
1071
1081
|
expects_public_file(dest)
|
1072
1082
|
end
|
1073
1083
|
|
1084
|
+
[0660, 0640, 0600, 0440].each do |mode|
|
1085
|
+
it "applies #{mode} mode" do
|
1086
|
+
Puppet::FileSystem.replace_file(dest, mode) { |f| f.write(content) }
|
1087
|
+
current_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_user_name)
|
1088
|
+
sd = Puppet::Util::Windows::Security.get_security_descriptor(dest)
|
1089
|
+
|
1090
|
+
expect(sd.dacl).to contain_exactly(
|
1091
|
+
an_object_having_attributes(sid: Puppet::Util::Windows::SID::LocalSystem, mask: 0x1f01ff),
|
1092
|
+
an_object_having_attributes(sid: Puppet::Util::Windows::SID::BuiltinAdministrators, mask: 0x1f01ff),
|
1093
|
+
an_object_having_attributes(sid: current_sid, mask: 0x1f01ff),
|
1094
|
+
)
|
1095
|
+
end
|
1096
|
+
end
|
1097
|
+
|
1074
1098
|
it 'raises Errno::EACCES if access is denied' do
|
1075
1099
|
allow(Puppet::Util::Windows::Security).to receive(:get_security_descriptor).and_raise(Puppet::Util::Windows::Error.new('access denied', 5))
|
1076
1100
|
|
@@ -3082,6 +3082,19 @@ describe "The lookup function" do
|
|
3082
3082
|
|
3083
3083
|
let(:env_data) { data_files }
|
3084
3084
|
|
3085
|
+
context 'with unencryptable eyaml' do
|
3086
|
+
let(:data_files) do
|
3087
|
+
{
|
3088
|
+
'common.eyaml' => <<-YAML.unindent
|
3089
|
+
key_with_invalid_eyaml: ENC[PKCS7,INVALID]
|
3090
|
+
YAML
|
3091
|
+
}
|
3092
|
+
end
|
3093
|
+
|
3094
|
+
it 'fails and reports error with ENC value, key being looked up and filename' do
|
3095
|
+
expect { lookup('key_with_invalid_eyaml') }.to raise_error(Puppet::DataBinding::LookupError, /hiera-eyaml backend error decrypting ENC\[PKCS7,INVALID\] when looking up key_with_invalid_eyaml in .*common\.eyaml\. Error was/)
|
3096
|
+
end
|
3097
|
+
end
|
3085
3098
|
context 'and a module using eyaml with different options' do
|
3086
3099
|
|
3087
3100
|
let(:private_module_key) do
|
@@ -4,7 +4,9 @@ require 'puppet/http'
|
|
4
4
|
|
5
5
|
describe Puppet::HTTP::Client do
|
6
6
|
let(:uri) { URI.parse('https://www.example.com') }
|
7
|
-
let(:
|
7
|
+
let(:puppet_context) { Puppet::SSL::SSLContext.new }
|
8
|
+
let(:system_context) { Puppet::SSL::SSLContext.new }
|
9
|
+
let(:client) { described_class.new(ssl_context: puppet_context, system_ssl_context: system_context) }
|
8
10
|
let(:credentials) { ['user', 'pass'] }
|
9
11
|
|
10
12
|
it 'creates unique sessions' do
|
@@ -45,6 +47,46 @@ describe Puppet::HTTP::Client do
|
|
45
47
|
client.connect(uri)
|
46
48
|
}.to raise_error(Puppet::HTTP::ConnectionError, %r{^Request to https://www.example.com timed out connect operation after .* seconds})
|
47
49
|
end
|
50
|
+
|
51
|
+
it 'connects using the default ssl context' do
|
52
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
53
|
+
expect(verifier.ssl_context).to equal(puppet_context)
|
54
|
+
end
|
55
|
+
|
56
|
+
client.connect(uri)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'connects using a specified ssl context' do
|
60
|
+
other_context = Puppet::SSL::SSLContext.new
|
61
|
+
|
62
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
63
|
+
expect(verifier.ssl_context).to equal(other_context)
|
64
|
+
end
|
65
|
+
|
66
|
+
client.connect(uri, options: {ssl_context: other_context})
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'connects using the system store' do
|
70
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
71
|
+
expect(verifier.ssl_context).to equal(system_context)
|
72
|
+
end
|
73
|
+
|
74
|
+
client.connect(uri, options: {include_system_store: true})
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not create a verifier for HTTP connections' do
|
78
|
+
expect(client.pool).to receive(:with_connection) do |_, verifier|
|
79
|
+
expect(verifier).to be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
client.connect(URI.parse('http://www.example.com'))
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'raises an HTTPError if both are specified' do
|
86
|
+
expect {
|
87
|
+
client.connect(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
88
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
89
|
+
end
|
48
90
|
end
|
49
91
|
|
50
92
|
context 'after connecting' do
|
@@ -75,10 +117,8 @@ describe Puppet::HTTP::Client do
|
|
75
117
|
|
76
118
|
context "when closing" do
|
77
119
|
it "closes all connections in the pool" do
|
78
|
-
pool
|
79
|
-
expect(pool).to receive(:close)
|
120
|
+
expect(client.pool).to receive(:close)
|
80
121
|
|
81
|
-
client = described_class.new(pool: pool)
|
82
122
|
client.close
|
83
123
|
end
|
84
124
|
end
|
@@ -99,6 +139,12 @@ describe Puppet::HTTP::Client do
|
|
99
139
|
client.get(uri, params: {:foo => "bar=baz"})
|
100
140
|
end
|
101
141
|
|
142
|
+
it "fails if a user passes in an invalid param type" do
|
143
|
+
environment = Puppet::Node::Environment.create(:testing, [])
|
144
|
+
|
145
|
+
expect{client.get(uri, params: {environment: environment})}.to raise_error(Puppet::HTTP::SerializationError, /HTTP REST queries cannot handle values of type/)
|
146
|
+
end
|
147
|
+
|
102
148
|
it "merges custom headers with default ones" do
|
103
149
|
stub_request(:get, uri).with(headers: { 'X-Foo' => 'Bar', 'X-Puppet-Version' => /./, 'User-Agent' => /./ })
|
104
150
|
|
@@ -132,6 +178,28 @@ describe Puppet::HTTP::Client do
|
|
132
178
|
|
133
179
|
expect(io.string).to eq("abc")
|
134
180
|
end
|
181
|
+
|
182
|
+
context 'when connecting' do
|
183
|
+
it 'uses a specified ssl context' do
|
184
|
+
stub_request(:get, uri).to_return(body: "abc")
|
185
|
+
|
186
|
+
other_context = Puppet::SSL::SSLContext.new
|
187
|
+
|
188
|
+
client.get(uri, options: {ssl_context: other_context})
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'uses the system store' do
|
192
|
+
stub_request(:get, uri).to_return(body: "abc")
|
193
|
+
|
194
|
+
client.get(uri, options: {include_system_store: true})
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'raises an HTTPError if both are specified' do
|
198
|
+
expect {
|
199
|
+
client.get(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
200
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
201
|
+
end
|
202
|
+
end
|
135
203
|
end
|
136
204
|
|
137
205
|
context "for HEAD requests" do
|
@@ -167,6 +235,28 @@ describe Puppet::HTTP::Client do
|
|
167
235
|
|
168
236
|
expect(client.head(uri).body).to eq("abc")
|
169
237
|
end
|
238
|
+
|
239
|
+
context 'when connecting' do
|
240
|
+
it 'uses a specified ssl context' do
|
241
|
+
stub_request(:head, uri)
|
242
|
+
|
243
|
+
other_context = Puppet::SSL::SSLContext.new
|
244
|
+
|
245
|
+
client.head(uri, options: {ssl_context: other_context})
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'uses the system store' do
|
249
|
+
stub_request(:head, uri)
|
250
|
+
|
251
|
+
client.head(uri, options: {include_system_store: true})
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'raises an HTTPError if both are specified' do
|
255
|
+
expect {
|
256
|
+
client.head(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
257
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
258
|
+
end
|
259
|
+
end
|
170
260
|
end
|
171
261
|
|
172
262
|
context "for PUT requests" do
|
@@ -176,25 +266,25 @@ describe Puppet::HTTP::Client do
|
|
176
266
|
expect(request.headers).to_not include('X-Puppet-Profiling')
|
177
267
|
end
|
178
268
|
|
179
|
-
client.put(uri,
|
269
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
|
180
270
|
end
|
181
271
|
|
182
272
|
it "stringifies keys and encodes values in the query" do
|
183
273
|
stub_request(:put, "https://www.example.com").with(query: "foo=bar%3Dbaz")
|
184
274
|
|
185
|
-
client.put(uri, params: {:foo => "bar=baz"},
|
275
|
+
client.put(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
|
186
276
|
end
|
187
277
|
|
188
278
|
it "includes custom headers" do
|
189
279
|
stub_request(:put, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
|
190
280
|
|
191
|
-
client.put(uri, headers: {'X-Foo' => 'Bar'
|
281
|
+
client.put(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
|
192
282
|
end
|
193
283
|
|
194
284
|
it "returns the response" do
|
195
285
|
stub_request(:put, uri)
|
196
286
|
|
197
|
-
response = client.put(uri,
|
287
|
+
response = client.put(uri, "", headers: {'Content-Type' => 'text/plain'})
|
198
288
|
expect(response).to be_an_instance_of(Puppet::HTTP::Response)
|
199
289
|
expect(response).to be_success
|
200
290
|
expect(response.code).to eq(200)
|
@@ -203,7 +293,41 @@ describe Puppet::HTTP::Client do
|
|
203
293
|
it "sets content-length and content-type for the body" do
|
204
294
|
stub_request(:put, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
|
205
295
|
|
206
|
-
client.put(uri,
|
296
|
+
client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'})
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'raises an ArgumentError if `body` is missing' do
|
300
|
+
expect {
|
301
|
+
client.put(uri, nil, headers: {'Content-Type' => 'text/plain'})
|
302
|
+
}.to raise_error(ArgumentError, /'put' requires a string 'body' argument/)
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
|
306
|
+
expect {
|
307
|
+
client.put(uri, '')
|
308
|
+
}.to raise_error(ArgumentError, /'put' requires a 'content-type' header/)
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when connecting' do
|
312
|
+
it 'uses a specified ssl context' do
|
313
|
+
stub_request(:put, uri)
|
314
|
+
|
315
|
+
other_context = Puppet::SSL::SSLContext.new
|
316
|
+
|
317
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: other_context})
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'uses the system store' do
|
321
|
+
stub_request(:put, uri)
|
322
|
+
|
323
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
|
324
|
+
end
|
325
|
+
|
326
|
+
it 'raises an HTTPError if both are specified' do
|
327
|
+
expect {
|
328
|
+
client.put(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
|
329
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
330
|
+
end
|
207
331
|
end
|
208
332
|
end
|
209
333
|
|
@@ -211,25 +335,25 @@ describe Puppet::HTTP::Client do
|
|
211
335
|
it "includes default HTTP headers" do
|
212
336
|
stub_request(:post, uri).with(headers: {'X-Puppet-Version' => /./, 'User-Agent' => /./})
|
213
337
|
|
214
|
-
client.post(uri,
|
338
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
|
215
339
|
end
|
216
340
|
|
217
341
|
it "stringifies keys and encodes values in the query" do
|
218
342
|
stub_request(:post, "https://www.example.com").with(query: "foo=bar%3Dbaz")
|
219
343
|
|
220
|
-
client.post(uri, params: {:foo => "bar=baz"},
|
344
|
+
client.post(uri, "", params: {:foo => "bar=baz"}, headers: {'Content-Type' => 'text/plain'})
|
221
345
|
end
|
222
346
|
|
223
347
|
it "includes custom headers" do
|
224
348
|
stub_request(:post, "https://www.example.com").with(headers: { 'X-Foo' => 'Bar' })
|
225
349
|
|
226
|
-
client.post(uri, headers: {'X-Foo' => 'Bar'
|
350
|
+
client.post(uri, "", headers: {'X-Foo' => 'Bar', 'Content-Type' => 'text/plain'})
|
227
351
|
end
|
228
352
|
|
229
353
|
it "returns the response" do
|
230
354
|
stub_request(:post, uri)
|
231
355
|
|
232
|
-
response = client.post(uri,
|
356
|
+
response = client.post(uri, "", headers: {'Content-Type' => 'text/plain'})
|
233
357
|
expect(response).to be_an_instance_of(Puppet::HTTP::Response)
|
234
358
|
expect(response).to be_success
|
235
359
|
expect(response.code).to eq(200)
|
@@ -238,14 +362,14 @@ describe Puppet::HTTP::Client do
|
|
238
362
|
it "sets content-length and content-type for the body" do
|
239
363
|
stub_request(:post, uri).with(headers: {"Content-Length" => "5", "Content-Type" => "text/plain"})
|
240
364
|
|
241
|
-
client.post(uri,
|
365
|
+
client.post(uri, "hello", headers: {'Content-Type' => 'text/plain'})
|
242
366
|
end
|
243
367
|
|
244
368
|
it "streams the response body when a block is given" do
|
245
369
|
stub_request(:post, uri).to_return(body: "abc")
|
246
370
|
|
247
371
|
io = StringIO.new
|
248
|
-
client.post(uri,
|
372
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}) do |response|
|
249
373
|
response.read_body do |data|
|
250
374
|
io.write(data)
|
251
375
|
end
|
@@ -253,6 +377,40 @@ describe Puppet::HTTP::Client do
|
|
253
377
|
|
254
378
|
expect(io.string).to eq("abc")
|
255
379
|
end
|
380
|
+
|
381
|
+
it 'raises an ArgumentError if `body` is missing' do
|
382
|
+
expect {
|
383
|
+
client.post(uri, nil, headers: {'Content-Type' => 'text/plain'})
|
384
|
+
}.to raise_error(ArgumentError, /'post' requires a string 'body' argument/)
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'raises an ArgumentError if `content_type` is missing from the headers hash' do
|
388
|
+
expect {
|
389
|
+
client.post(uri, "")
|
390
|
+
}.to raise_error(ArgumentError, /'post' requires a 'content-type' header/)
|
391
|
+
end
|
392
|
+
|
393
|
+
context 'when connecting' do
|
394
|
+
it 'uses a specified ssl context' do
|
395
|
+
stub_request(:post, uri)
|
396
|
+
|
397
|
+
other_context = Puppet::SSL::SSLContext.new
|
398
|
+
|
399
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {body: "", ssl_context: other_context})
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'uses the system store' do
|
403
|
+
stub_request(:post, uri)
|
404
|
+
|
405
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {include_system_store: true})
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'raises an HTTPError if both are specified' do
|
409
|
+
expect {
|
410
|
+
client.post(uri, "", headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: puppet_context, include_system_store: true})
|
411
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
412
|
+
end
|
413
|
+
end
|
256
414
|
end
|
257
415
|
|
258
416
|
context "for DELETE requests" do
|
@@ -288,44 +446,80 @@ describe Puppet::HTTP::Client do
|
|
288
446
|
|
289
447
|
expect(client.delete(uri).body).to eq("abc")
|
290
448
|
end
|
449
|
+
|
450
|
+
context 'when connecting' do
|
451
|
+
it 'uses a specified ssl context' do
|
452
|
+
stub_request(:delete, uri)
|
453
|
+
|
454
|
+
other_context = Puppet::SSL::SSLContext.new
|
455
|
+
|
456
|
+
client.delete(uri, options: {ssl_context: other_context})
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'uses the system store' do
|
460
|
+
stub_request(:delete, uri)
|
461
|
+
|
462
|
+
client.delete(uri, options: {include_system_store: true})
|
463
|
+
end
|
464
|
+
|
465
|
+
it 'raises an HTTPError if both are specified' do
|
466
|
+
expect {
|
467
|
+
client.delete(uri, options: {ssl_context: puppet_context, include_system_store: true})
|
468
|
+
}.to raise_error(Puppet::HTTP::HTTPError, /The ssl_context and include_system_store parameters are mutually exclusive/)
|
469
|
+
end
|
470
|
+
end
|
291
471
|
end
|
292
472
|
|
293
473
|
context "Basic Auth" do
|
294
474
|
it "submits credentials for GET requests" do
|
295
475
|
stub_request(:get, uri).with(basic_auth: credentials)
|
296
476
|
|
297
|
-
client.get(uri, user: 'user', password: 'pass')
|
477
|
+
client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
|
298
478
|
end
|
299
479
|
|
300
480
|
it "submits credentials for PUT requests" do
|
301
481
|
stub_request(:put, uri).with(basic_auth: credentials)
|
302
482
|
|
303
|
-
client.put(uri,
|
483
|
+
client.put(uri, "hello", headers: {'Content-Type' => 'text/plain'}, options: {basic_auth: {user: 'user', password: 'pass'}})
|
304
484
|
end
|
305
485
|
|
306
486
|
it "returns response containing access denied" do
|
307
487
|
stub_request(:get, uri).with(basic_auth: credentials).to_return(status: [403, "Ye Shall Not Pass"])
|
308
488
|
|
309
|
-
response = client.get(uri, user: 'user', password: 'pass')
|
489
|
+
response = client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
|
310
490
|
expect(response.code).to eq(403)
|
311
491
|
expect(response.reason).to eq("Ye Shall Not Pass")
|
312
492
|
expect(response).to_not be_success
|
313
493
|
end
|
314
494
|
|
315
|
-
it '
|
495
|
+
it 'includes basic auth if user is nil' do
|
316
496
|
stub_request(:get, uri).with do |req|
|
317
|
-
expect(req.headers).
|
497
|
+
expect(req.headers).to include('Authorization')
|
318
498
|
end
|
319
499
|
|
320
|
-
client.get(uri, user: nil, password: 'pass')
|
500
|
+
client.get(uri, options: {basic_auth: {user: nil, password: 'pass'}})
|
321
501
|
end
|
322
502
|
|
323
|
-
it '
|
503
|
+
it 'includes basic auth if password is nil' do
|
324
504
|
stub_request(:get, uri).with do |req|
|
325
|
-
expect(req.headers).
|
505
|
+
expect(req.headers).to include('Authorization')
|
326
506
|
end
|
327
507
|
|
328
|
-
client.get(uri, user: 'user', password: nil)
|
508
|
+
client.get(uri, options: {basic_auth: {user: 'user', password: nil}})
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'observes userinfo in the URL' do
|
512
|
+
stub_request(:get, uri).with(basic_auth: credentials)
|
513
|
+
|
514
|
+
client.get(URI("https://user:pass@www.example.com"))
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'prefers explicit basic_auth credentials' do
|
518
|
+
uri = URI("https://ignored_user:ignored_pass@www.example.com")
|
519
|
+
|
520
|
+
stub_request(:get, "https://www.example.com").with(basic_auth: credentials)
|
521
|
+
|
522
|
+
client.get(uri, options: {basic_auth: {user: 'user', password: 'pass'}})
|
329
523
|
end
|
330
524
|
end
|
331
525
|
|
@@ -351,14 +545,45 @@ describe Puppet::HTTP::Client do
|
|
351
545
|
stub_request(:put, start_url).to_return(redirect_to(url: bar_url))
|
352
546
|
stub_request(:put, bar_url).to_return(status: 200)
|
353
547
|
|
354
|
-
response = client.put(start_url,
|
548
|
+
response = client.put(start_url, "", headers: {'Content-Type' => 'text/plain'})
|
549
|
+
expect(response).to be_success
|
550
|
+
end
|
551
|
+
|
552
|
+
it "updates the Host header from the Location host and port" do
|
553
|
+
stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
|
554
|
+
.to_return(redirect_to(url: other_host))
|
555
|
+
stub_request(:get, other_host).with(headers: { 'Host' => 'other.example.com:8140' })
|
556
|
+
.to_return(status: 200)
|
557
|
+
|
558
|
+
response = client.get(start_url)
|
559
|
+
expect(response).to be_success
|
560
|
+
end
|
561
|
+
|
562
|
+
it "omits the default HTTPS port from the Host header" do
|
563
|
+
stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
|
564
|
+
.to_return(redirect_to(url: "https://other.example.com/qux"))
|
565
|
+
stub_request(:get, "https://other.example.com/qux").with(headers: { 'Host' => 'other.example.com' })
|
566
|
+
.to_return(status: 200)
|
567
|
+
|
568
|
+
response = client.get(start_url)
|
569
|
+
expect(response).to be_success
|
570
|
+
end
|
571
|
+
|
572
|
+
it "omits the default HTTP port from the Host header" do
|
573
|
+
stub_request(:get, start_url).with(headers: { 'Host' => 'www.example.com:8140' })
|
574
|
+
.to_return(redirect_to(url: "http://other.example.com/qux"))
|
575
|
+
stub_request(:get, "http://other.example.com/qux").with(headers: { 'Host' => 'other.example.com' })
|
576
|
+
.to_return(status: 200)
|
577
|
+
|
578
|
+
response = client.get(start_url)
|
355
579
|
expect(response).to be_success
|
356
580
|
end
|
357
581
|
|
358
|
-
it "
|
359
|
-
query = { '
|
360
|
-
|
361
|
-
stub_request(:get,
|
582
|
+
it "applies query parameters from the location header" do
|
583
|
+
query = { 'redirected' => false }
|
584
|
+
|
585
|
+
stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: "#{bar_url}?redirected=true"))
|
586
|
+
stub_request(:get, bar_url).with(query: {'redirected' => 'true'}).to_return(status: 200)
|
362
587
|
|
363
588
|
response = client.get(start_url, params: query)
|
364
589
|
expect(response).to be_success
|
@@ -377,7 +602,7 @@ describe Puppet::HTTP::Client do
|
|
377
602
|
stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
|
378
603
|
stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
|
379
604
|
|
380
|
-
client.get(start_url, user: 'user', password: 'pass')
|
605
|
+
client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
|
381
606
|
end
|
382
607
|
|
383
608
|
it "redirects given a relative location" do
|
@@ -389,22 +614,33 @@ describe Puppet::HTTP::Client do
|
|
389
614
|
expect(response).to be_success
|
390
615
|
end
|
391
616
|
|
392
|
-
it "
|
617
|
+
it "applies query parameters from the location header" do
|
393
618
|
relative_url = "/people.html"
|
394
|
-
query = { '
|
395
|
-
stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: relative_url))
|
396
|
-
stub_request(:get, "https://www.example.com:8140/people.html").with(query:
|
619
|
+
query = { 'redirected' => false }
|
620
|
+
stub_request(:get, start_url).with(query: query).to_return(redirect_to(url: "#{relative_url}?redirected=true"))
|
621
|
+
stub_request(:get, "https://www.example.com:8140/people.html").with(query: {'redirected' => 'true'}).to_return(status: 200)
|
397
622
|
|
398
623
|
response = client.get(start_url, params: query)
|
399
624
|
expect(response).to be_success
|
400
625
|
end
|
401
626
|
|
627
|
+
it "removes dot segments from a relative location" do
|
628
|
+
# from https://tools.ietf.org/html/rfc3986#section-5.4.2
|
629
|
+
base_url = URI("http://a/b/c/d;p?q")
|
630
|
+
relative_url = "../../../../g"
|
631
|
+
stub_request(:get, base_url).to_return(redirect_to(url: relative_url))
|
632
|
+
stub_request(:get, "http://a/g").to_return(status: 200)
|
633
|
+
|
634
|
+
response = client.get(base_url)
|
635
|
+
expect(response).to be_success
|
636
|
+
end
|
637
|
+
|
402
638
|
it "preserves request body for each request" do
|
403
639
|
data = 'some data'
|
404
640
|
stub_request(:put, start_url).with(body: data).to_return(redirect_to(url: bar_url))
|
405
641
|
stub_request(:put, bar_url).with(body: data).to_return(status: 200)
|
406
642
|
|
407
|
-
response = client.put(start_url,
|
643
|
+
response = client.put(start_url, data, headers: {'Content-Type' => 'text/plain'})
|
408
644
|
expect(response).to be_success
|
409
645
|
end
|
410
646
|
|
@@ -533,6 +769,32 @@ describe Puppet::HTTP::Client do
|
|
533
769
|
}.to raise_error(Puppet::HTTP::ProtocolError, /Failed to parse Retry-After header 'foo' as an integer or RFC 2822 date/)
|
534
770
|
end
|
535
771
|
|
772
|
+
it "should close the connection before sleeping" do
|
773
|
+
retry_after('42')
|
774
|
+
|
775
|
+
site = Puppet::Network::HTTP::Site.from_uri(uri)
|
776
|
+
|
777
|
+
http1 = Net::HTTP.new(site.host, site.port)
|
778
|
+
http1.use_ssl = true
|
779
|
+
allow(http1).to receive(:started?).and_return(true)
|
780
|
+
|
781
|
+
http2 = Net::HTTP.new(site.host, site.port)
|
782
|
+
http2.use_ssl = true
|
783
|
+
allow(http2).to receive(:started?).and_return(true)
|
784
|
+
|
785
|
+
|
786
|
+
pool = Puppet::Network::HTTP::Pool.new(15)
|
787
|
+
client = Puppet::HTTP::Client.new(pool: pool)
|
788
|
+
|
789
|
+
# The "with_connection" method is required to yield started connections
|
790
|
+
allow(pool).to receive(:with_connection).and_yield(http1).and_yield(http2)
|
791
|
+
|
792
|
+
expect(http1).to receive(:finish).ordered
|
793
|
+
expect(::Kernel).to receive(:sleep).with(42).ordered
|
794
|
+
|
795
|
+
client.get(uri)
|
796
|
+
end
|
797
|
+
|
536
798
|
it "should sleep and retry if Retry-After is an Integer" do
|
537
799
|
retry_after('42')
|
538
800
|
|
@@ -569,4 +831,34 @@ describe Puppet::HTTP::Client do
|
|
569
831
|
client.get(uri)
|
570
832
|
end
|
571
833
|
end
|
834
|
+
|
835
|
+
context "persistent connections" do
|
836
|
+
before :each do
|
837
|
+
stub_request(:get, uri)
|
838
|
+
end
|
839
|
+
|
840
|
+
it 'defaults keepalive to http_keepalive_timeout' do
|
841
|
+
expect(client.pool.keepalive_timeout).to eq(Puppet[:http_keepalive_timeout])
|
842
|
+
end
|
843
|
+
|
844
|
+
it 'reuses a cached connection' do
|
845
|
+
allow(Puppet).to receive(:debug)
|
846
|
+
expect(Puppet).to receive(:debug).with(/^Creating new connection/)
|
847
|
+
expect(Puppet).to receive(:debug).with(/^Using cached connection/)
|
848
|
+
|
849
|
+
client.get(uri)
|
850
|
+
client.get(uri)
|
851
|
+
end
|
852
|
+
|
853
|
+
it 'can be disabled' do
|
854
|
+
Puppet[:http_keepalive_timeout] = 0
|
855
|
+
|
856
|
+
allow(Puppet).to receive(:debug)
|
857
|
+
expect(Puppet).to receive(:debug).with(/^Creating new connection/).twice
|
858
|
+
expect(Puppet).to receive(:debug).with(/^Using cached connection/).never
|
859
|
+
|
860
|
+
client.get(uri)
|
861
|
+
client.get(uri)
|
862
|
+
end
|
863
|
+
end
|
572
864
|
end
|