puppet 5.5.16-x86-mingw32 → 5.5.21-x86-mingw32
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 +10 -10
- data/Gemfile +2 -3
- data/Gemfile.lock +57 -52
- data/ext/build_defaults.yaml +1 -0
- data/ext/cert_inspector +3 -3
- data/ext/project_data.yaml +2 -2
- data/ext/puppet-test +2 -2
- data/ext/regexp_nodes/regexp_nodes.rb +4 -4
- data/ext/windows/service/daemon.rb +54 -8
- data/install.rb +6 -24
- data/lib/puppet.rb +5 -2
- data/lib/puppet/agent.rb +5 -13
- data/lib/puppet/application.rb +1 -1
- data/lib/puppet/application/agent.rb +15 -1
- data/lib/puppet/application/apply.rb +2 -2
- data/lib/puppet/application/describe.rb +3 -9
- data/lib/puppet/application/device.rb +4 -4
- data/lib/puppet/application/doc.rb +1 -1
- data/lib/puppet/application/filebucket.rb +13 -0
- data/lib/puppet/application/lookup.rb +1 -1
- data/lib/puppet/application/resource.rb +4 -4
- data/lib/puppet/application/script.rb +2 -2
- data/lib/puppet/configurer.rb +86 -28
- data/lib/puppet/configurer/downloader.rb +2 -6
- data/lib/puppet/daemon.rb +1 -1
- data/lib/puppet/defaults.rb +82 -38
- data/lib/puppet/error.rb +9 -1
- data/lib/puppet/external/nagios/base.rb +1 -1
- data/lib/puppet/face/ca.rb +1 -1
- data/lib/puppet/face/config.rb +10 -48
- data/lib/puppet/face/facts.rb +1 -1
- data/lib/puppet/face/module/list.rb +5 -5
- data/lib/puppet/face/module/search.rb +1 -1
- data/lib/puppet/face/module/uninstall.rb +1 -1
- data/lib/puppet/face/module/upgrade.rb +1 -1
- data/lib/puppet/face/plugin.rb +9 -2
- data/lib/puppet/file_serving/http_metadata.rb +1 -1
- data/lib/puppet/file_system.rb +0 -8
- data/lib/puppet/file_system/memory_file.rb +1 -1
- data/lib/puppet/file_system/posix.rb +3 -2
- data/lib/puppet/file_system/uniquefile.rb +4 -0
- data/lib/puppet/forge.rb +3 -3
- data/lib/puppet/functions/epp.rb +4 -4
- data/lib/puppet/functions/inline_epp.rb +5 -5
- data/lib/puppet/functions/reduce.rb +2 -4
- data/lib/puppet/gettext/module_translations.rb +1 -1
- data/lib/puppet/graph/rb_tree_map.rb +2 -2
- data/lib/puppet/graph/simple_graph.rb +6 -5
- data/lib/puppet/indirector/catalog/compiler.rb +8 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/lib/puppet/indirector/hiera.rb +2 -0
- data/lib/puppet/indirector/resource/ral.rb +1 -3
- data/lib/puppet/indirector/resource/validator.rb +1 -1
- data/lib/puppet/interface.rb +2 -1
- data/lib/puppet/loaders.rb +0 -1
- data/lib/puppet/metatype/manager.rb +1 -1
- data/lib/puppet/module.rb +1 -1
- data/lib/puppet/module_tool/applications/builder.rb +1 -1
- data/lib/puppet/module_tool/applications/installer.rb +1 -1
- data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
- data/lib/puppet/module_tool/metadata.rb +1 -1
- data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
- data/lib/puppet/module_tool/tar/mini.rb +12 -2
- data/lib/puppet/network/http/api/indirected_routes.rb +13 -12
- data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
- data/lib/puppet/network/http/connection.rb +14 -12
- data/lib/puppet/network/http/factory.rb +1 -11
- data/lib/puppet/network/http/pool.rb +7 -1
- data/lib/puppet/network/http/rack/rest.rb +2 -2
- data/lib/puppet/network/http/site.rb +1 -1
- data/lib/puppet/network/resolver.rb +2 -2
- data/lib/puppet/node/environment.rb +4 -2
- data/lib/puppet/parameter.rb +8 -0
- data/lib/puppet/parser/ast.rb +1 -1
- data/lib/puppet/parser/ast/resourceparam.rb +1 -1
- 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 +3 -0
- data/lib/puppet/parser/functions.rb +1 -1
- data/lib/puppet/parser/functions/epp.rb +3 -3
- data/lib/puppet/parser/functions/inline_epp.rb +5 -5
- 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/collectors/catalog_collector.rb +1 -1
- data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
- data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -2
- data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -4
- data/lib/puppet/pops/issues.rb +5 -0
- data/lib/puppet/pops/loaders.rb +1 -1
- data/lib/puppet/pops/lookup/hiera_config.rb +1 -0
- data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
- data/lib/puppet/pops/merge_strategy.rb +22 -18
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
- data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
- data/lib/puppet/pops/parser/locator.rb +1 -1
- data/lib/puppet/pops/parser/pn_parser.rb +17 -16
- data/lib/puppet/pops/puppet_stack.rb +51 -48
- data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
- data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
- data/lib/puppet/pops/types/string_converter.rb +10 -10
- data/lib/puppet/pops/types/type_calculator.rb +24 -0
- data/lib/puppet/pops/types/types.rb +3 -3
- data/lib/puppet/pops/validation/checker4_0.rb +10 -0
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/property.rb +1 -1
- data/lib/puppet/property/ensure.rb +1 -1
- data/lib/puppet/provider/augeas/augeas.rb +1 -1
- data/lib/puppet/provider/cron/crontab.rb +1 -1
- data/lib/puppet/provider/exec.rb +6 -2
- data/lib/puppet/provider/file/posix.rb +5 -0
- data/lib/puppet/provider/group/groupadd.rb +19 -19
- data/lib/puppet/provider/group/windows_adsi.rb +3 -3
- data/lib/puppet/provider/mailalias/aliases.rb +1 -1
- data/lib/puppet/provider/mount.rb +1 -1
- data/lib/puppet/provider/mount/parsed.rb +8 -8
- data/lib/puppet/provider/nameservice.rb +10 -3
- data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
- data/lib/puppet/provider/nameservice/pw.rb +2 -2
- data/lib/puppet/provider/package/aix.rb +17 -2
- data/lib/puppet/provider/package/apt.rb +14 -3
- data/lib/puppet/provider/package/dnf.rb +1 -1
- data/lib/puppet/provider/package/dnfmodule.rb +141 -0
- data/lib/puppet/provider/package/dpkg.rb +16 -18
- data/lib/puppet/provider/package/fink.rb +20 -3
- data/lib/puppet/provider/package/openbsd.rb +14 -2
- data/lib/puppet/provider/package/pip.rb +37 -10
- 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 +4 -4
- data/lib/puppet/provider/package/rpm.rb +57 -19
- data/lib/puppet/provider/package/windows/package.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +35 -24
- data/lib/puppet/provider/package/zypper.rb +1 -0
- data/lib/puppet/provider/package_targetable.rb +5 -4
- data/lib/puppet/provider/parsedfile.rb +1 -1
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +3 -3
- data/lib/puppet/provider/selmodule/semodule.rb +43 -26
- data/lib/puppet/provider/service/daemontools.rb +9 -9
- data/lib/puppet/provider/service/launchd.rb +20 -5
- data/lib/puppet/provider/service/openbsd.rb +1 -1
- data/lib/puppet/provider/service/rcng.rb +2 -2
- data/lib/puppet/provider/service/runit.rb +2 -8
- data/lib/puppet/provider/service/systemd.rb +35 -22
- data/lib/puppet/provider/service/windows.rb +8 -0
- data/lib/puppet/provider/user/directoryservice.rb +31 -6
- data/lib/puppet/provider/user/hpux.rb +1 -1
- data/lib/puppet/provider/user/pw.rb +12 -3
- data/lib/puppet/provider/user/user_role_add.rb +5 -1
- data/lib/puppet/provider/user/useradd.rb +62 -27
- data/lib/puppet/provider/user/windows_adsi.rb +4 -5
- data/lib/puppet/provider/yumrepo/inifile.rb +2 -2
- data/lib/puppet/reference/indirection.rb +2 -2
- data/lib/puppet/reference/metaparameter.rb +1 -3
- data/lib/puppet/reference/providers.rb +1 -1
- data/lib/puppet/reference/type.rb +3 -9
- data/lib/puppet/reports.rb +1 -1
- data/lib/puppet/resource.rb +18 -1
- data/lib/puppet/resource/catalog.rb +1 -1
- data/lib/puppet/resource/type.rb +8 -0
- data/lib/puppet/settings.rb +43 -3
- data/lib/puppet/settings/environment_conf.rb +1 -0
- data/lib/puppet/ssl/certificate.rb +2 -1
- data/lib/puppet/ssl/certificate_authority.rb +6 -5
- data/lib/puppet/ssl/certificate_authority/interface.rb +1 -1
- data/lib/puppet/ssl/certificate_factory.rb +2 -2
- data/lib/puppet/ssl/host.rb +3 -3
- data/lib/puppet/ssl/oids.rb +1 -1
- data/lib/puppet/test/test_helper.rb +15 -10
- data/lib/puppet/transaction/report.rb +1 -1
- data/lib/puppet/transaction/resource_harness.rb +1 -1
- data/lib/puppet/type.rb +15 -4
- data/lib/puppet/type/cron.rb +1 -1
- data/lib/puppet/type/exec.rb +21 -9
- data/lib/puppet/type/file.rb +14 -2
- data/lib/puppet/type/file/data_sync.rb +5 -1
- data/lib/puppet/type/group.rb +4 -2
- data/lib/puppet/type/interface.rb +1 -1
- data/lib/puppet/type/notify.rb +3 -2
- data/lib/puppet/type/package.rb +107 -8
- data/lib/puppet/type/schedule.rb +1 -1
- data/lib/puppet/type/selboolean.rb +17 -3
- data/lib/puppet/type/service.rb +9 -10
- data/lib/puppet/type/user.rb +6 -24
- data/lib/puppet/type/yumrepo.rb +3 -7
- data/lib/puppet/util.rb +47 -25
- data/lib/puppet/util/command_line/trollop.rb +1 -1
- data/lib/puppet/util/execution.rb +4 -3
- data/lib/puppet/util/http_proxy.rb +24 -16
- data/lib/puppet/util/instance_loader.rb +1 -1
- data/lib/puppet/util/log.rb +1 -1
- data/lib/puppet/util/log/destinations.rb +3 -12
- data/lib/puppet/util/logging.rb +30 -18
- data/lib/puppet/util/metric.rb +2 -2
- data/lib/puppet/util/monkey_patches.rb +1 -1
- data/lib/puppet/util/nagios_maker.rb +2 -2
- data/lib/puppet/util/network_device/cisco/device.rb +1 -1
- data/lib/puppet/util/network_device/cisco/interface.rb +2 -2
- data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
- data/lib/puppet/util/pidlock.rb +12 -6
- data/lib/puppet/util/plist.rb +6 -0
- data/lib/puppet/util/provider_features.rb +2 -4
- data/lib/puppet/util/rdoc.rb +1 -1
- data/lib/puppet/util/reference.rb +1 -1
- data/lib/puppet/util/resource_template.rb +1 -1
- data/lib/puppet/util/selinux.rb +8 -2
- data/lib/puppet/util/windows/adsi.rb +60 -30
- 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 +16 -15
- data/lib/puppet/util/windows/registry.rb +17 -15
- data/lib/puppet/util/windows/security.rb +3 -0
- data/lib/puppet/util/windows/service.rb +149 -4
- data/lib/puppet/util/windows/sid.rb +4 -3
- data/lib/puppet/vendor.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet_pal.rb +2 -2
- data/locales/puppet.pot +479 -443
- data/man/man5/puppet.conf.5 +38 -8
- data/man/man8/puppet-agent.8 +2 -2
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-ca.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-cert.8 +1 -1
- data/man/man8/puppet-certificate.8 +1 -1
- data/man/man8/puppet-certificate_request.8 +1 -1
- data/man/man8/puppet-certificate_revocation_list.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 +1 -1
- 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 +16 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- 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-master.8 +1 -1
- data/man/man8/puppet-module.8 +1 -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-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/integration/provider/mailalias/aliases/test1 +1 -0
- data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list.txt +19 -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/service/systemd/list_unit_files_services +9 -0
- data/spec/integration/configurer_spec.rb +52 -0
- data/spec/integration/defaults_spec.rb +1 -2
- data/spec/integration/indirector/facts/facter_spec.rb +4 -0
- data/spec/integration/parser/compiler_spec.rb +11 -0
- data/spec/integration/provider/service/systemd_spec.rb +8 -5
- data/spec/integration/type/file_spec.rb +28 -0
- data/spec/integration/type/notify_spec.rb +46 -0
- data/spec/integration/util/execution_spec.rb +27 -0
- data/spec/integration/util/windows/adsi_spec.rb +6 -1
- data/spec/integration/util/windows/registry_spec.rb +7 -7
- data/spec/unit/agent_spec.rb +34 -26
- data/spec/unit/application/agent_spec.rb +18 -0
- data/spec/unit/application/apply_spec.rb +2 -12
- data/spec/unit/application/device_spec.rb +1 -1
- data/spec/unit/configurer/fact_handler_spec.rb +0 -4
- data/spec/unit/configurer_spec.rb +377 -397
- data/spec/unit/daemon_spec.rb +0 -1
- data/spec/unit/face/facts_spec.rb +9 -0
- data/spec/unit/face/plugin_spec.rb +8 -0
- data/spec/unit/file_system/uniquefile_spec.rb +11 -0
- data/spec/unit/forge/forge_spec.rb +1 -3
- data/spec/unit/forge/repository_spec.rb +1 -3
- data/spec/unit/indirector/catalog/compiler_spec.rb +45 -26
- data/spec/unit/indirector/resource/ral_spec.rb +4 -4
- data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
- data/spec/unit/network/http/api/indirected_routes_spec.rb +28 -11
- data/spec/unit/network/http/connection_spec.rb +43 -1
- data/spec/unit/network/http/factory_spec.rb +27 -5
- data/spec/unit/network/http/pool_spec.rb +32 -0
- data/spec/unit/node_spec.rb +7 -4
- data/spec/unit/parser/environment_compiler_spec.rb +7 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
- data/spec/unit/pops/validator/validator_spec.rb +7 -0
- data/spec/unit/provider/exec_spec.rb +209 -0
- data/spec/unit/provider/group/groupadd_spec.rb +30 -1
- 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 +13 -2
- data/spec/unit/provider/package/aptitude_spec.rb +1 -0
- data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
- data/spec/unit/provider/package/dnf_spec.rb +7 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +247 -0
- data/spec/unit/provider/package/dpkg_spec.rb +35 -7
- data/spec/unit/provider/package/openbsd_spec.rb +17 -0
- data/spec/unit/provider/package/pip_spec.rb +93 -22
- data/spec/unit/provider/package/pkg_spec.rb +13 -1
- data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
- data/spec/unit/provider/package/pkgng_spec.rb +36 -0
- data/spec/unit/provider/package/portage_spec.rb +4 -4
- data/spec/unit/provider/package/rpm_spec.rb +150 -16
- data/spec/unit/provider/package/yum_spec.rb +66 -0
- data/spec/unit/provider/package/zypper_spec.rb +13 -0
- data/spec/unit/provider/package_targetable_spec.rb +60 -0
- data/spec/unit/provider/selmodule_spec.rb +118 -47
- data/spec/unit/provider/service/daemontools_spec.rb +24 -0
- data/spec/unit/provider/service/launchd_spec.rb +28 -0
- data/spec/unit/provider/service/runit_spec.rb +24 -0
- data/spec/unit/provider/service/systemd_spec.rb +109 -36
- data/spec/unit/provider/service/windows_spec.rb +20 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
- data/spec/unit/provider/user/hpux_spec.rb +2 -2
- data/spec/unit/provider/user/openbsd_spec.rb +1 -0
- data/spec/unit/provider/user/pw_spec.rb +37 -0
- data/spec/unit/provider/user/useradd_spec.rb +122 -15
- data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
- data/spec/unit/puppet_pal_2pec.rb +3 -0
- data/spec/unit/resource_spec.rb +26 -1
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -3
- data/spec/unit/ssl/certificate_spec.rb +7 -0
- data/spec/unit/test/test_helper_spec.rb +17 -0
- data/spec/unit/transaction_spec.rb +18 -0
- data/spec/unit/type/exec_spec.rb +15 -12
- data/spec/unit/type/file/content_spec.rb +9 -3
- data/spec/unit/type/file/source_spec.rb +4 -4
- data/spec/unit/type/file_spec.rb +9 -4
- data/spec/unit/type/package_spec.rb +8 -0
- data/spec/unit/type/schedule_spec.rb +3 -1
- data/spec/unit/type/selboolean_spec.rb +4 -6
- data/spec/unit/type/service_spec.rb +25 -8
- data/spec/unit/type/user_spec.rb +32 -26
- data/spec/unit/type/yumrepo_spec.rb +30 -0
- data/spec/unit/type_spec.rb +40 -0
- data/spec/unit/util/execution_spec.rb +16 -0
- data/spec/unit/util/http_proxy_spec.rb +121 -1
- data/spec/unit/util/log/destinations_spec.rb +2 -26
- data/spec/unit/util/log_spec.rb +0 -112
- data/spec/unit/util/logging_spec.rb +200 -0
- data/spec/unit/util/pidlock_spec.rb +67 -40
- data/spec/unit/util/plist_spec.rb +20 -0
- data/spec/unit/util/windows/adsi_spec.rb +55 -4
- data/spec/unit/util/windows/api_types_spec.rb +104 -40
- data/spec/unit/util/windows/service_spec.rb +9 -0
- data/spec/unit/util/windows/sid_spec.rb +2 -2
- data/tasks/manpages.rake +1 -0
- metadata +18 -13
- data/ext/windows/eventlog/Rakefile +0 -32
- data/ext/windows/eventlog/puppetres.dll +0 -0
- data/ext/windows/eventlog/puppetres.mc +0 -18
- data/lib/puppet/pops/loader/null_loader.rb +0 -60
- data/locales/ja/puppet.po +0 -12114
- data/spec/integration/test/test_helper_spec.rb +0 -31
data/spec/unit/daemon_spec.rb
CHANGED
@@ -224,7 +224,6 @@ describe Puppet::Daemon, :unless => Puppet.features.microsoft_windows? do
|
|
224
224
|
end
|
225
225
|
|
226
226
|
it "should reexec itself if the agent is not running" do
|
227
|
-
expect(agent).to receive(:running?).and_return(false)
|
228
227
|
daemon.agent = agent
|
229
228
|
expect(daemon).to receive(:reexec)
|
230
229
|
|
@@ -45,6 +45,15 @@ CONF
|
|
45
45
|
subject.upload
|
46
46
|
end
|
47
47
|
|
48
|
+
it "passes the current environment" do
|
49
|
+
env = Puppet::Node::Environment.remote('qa')
|
50
|
+
expect(model.indirection).to receive(:save).with(anything, nil, :environment => env)
|
51
|
+
|
52
|
+
Puppet.override(:current_environment => env) do
|
53
|
+
subject.upload
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
48
57
|
it "uses settings from the agent section of puppet.conf" do
|
49
58
|
expect(facter_terminus).to receive(:find).with(have_attributes(key: 'puppet.node.test')).and_return(test_data)
|
50
59
|
|
@@ -50,6 +50,14 @@ describe Puppet::Face[:plugin, :current] do
|
|
50
50
|
expect(receive_count).to eq(3)
|
51
51
|
expect(render(result)).to eq('Downloaded these plugins: /a, /b, /c')
|
52
52
|
end
|
53
|
+
|
54
|
+
it "uses persistent HTTP pool" do
|
55
|
+
allow_any_instance_of(Puppet::Configurer::Downloader).to receive(:evaluate) do
|
56
|
+
expect(Puppet.lookup(:http_pool)).to be_instance_of(Puppet::Network::HTTP::Pool)
|
57
|
+
end.and_return([])
|
58
|
+
|
59
|
+
pluginface.download
|
60
|
+
end
|
53
61
|
end
|
54
62
|
|
55
63
|
context "download when server_agent_version is 5.3.3" do
|
@@ -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/)
|
@@ -67,6 +69,15 @@ describe Puppet::FileSystem::Uniquefile do
|
|
67
69
|
Puppet::FileSystem::Uniquefile.open_tmp('foo') { |tmp| }
|
68
70
|
end
|
69
71
|
|
72
|
+
it "reports when a parent directory does not exist" do
|
73
|
+
dir = tmpdir('uniquefile')
|
74
|
+
lock = File.join(dir, 'path', 'to', 'lock')
|
75
|
+
|
76
|
+
expect {
|
77
|
+
Puppet::FileSystem::Uniquefile.open_tmp(lock) { |tmp| }
|
78
|
+
}.to raise_error(Errno::ENOENT, %r{No such file or directory - A directory component in .* does not exist or is a dangling symbolic link})
|
79
|
+
end
|
80
|
+
|
70
81
|
context "Ruby 1.9.3 Tempfile tests" do
|
71
82
|
# the remaining tests in this file are ported directly from the ruby 1.9.3 source,
|
72
83
|
# since most of this file was ported from there
|
@@ -97,10 +97,8 @@ describe Puppet::Forge do
|
|
97
97
|
def mock_proxy(port, proxy_args, result, &block)
|
98
98
|
http = double("http client")
|
99
99
|
proxy = double("http proxy")
|
100
|
-
proxy_class = double("http proxy class")
|
101
100
|
|
102
|
-
expect(Net::HTTP).to receive(:
|
103
|
-
expect(proxy_class).to receive(:new).with(host, port).and_return(proxy)
|
101
|
+
expect(Net::HTTP).to receive(:new).with(host, port, *proxy_args).and_return(proxy)
|
104
102
|
|
105
103
|
expect(proxy).to receive(:open_timeout=)
|
106
104
|
expect(proxy).to receive(:read_timeout=)
|
@@ -234,10 +234,8 @@ describe Puppet::Forge::Repository do
|
|
234
234
|
def mock_proxy(port, proxy_args, result, &block)
|
235
235
|
http = double("http client")
|
236
236
|
proxy = double("http proxy")
|
237
|
-
proxy_class = double("http proxy class")
|
238
237
|
|
239
|
-
expect(Net::HTTP).to receive(:
|
240
|
-
expect(proxy_class).to receive(:new).with("fake.com", port).and_return(proxy)
|
238
|
+
expect(Net::HTTP).to receive(:new).with("fake.com", port, *proxy_args).and_return(proxy)
|
241
239
|
|
242
240
|
expect(proxy).to receive(:open_timeout=)
|
243
241
|
expect(proxy).to receive(:read_timeout=)
|
@@ -9,19 +9,9 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
9
9
|
let(:node_name) { "foo" }
|
10
10
|
let(:node) { Puppet::Node.new(node_name)}
|
11
11
|
|
12
|
-
before do
|
13
|
-
allow(Facter).to receive(:to_hash).and_return({})
|
14
|
-
end
|
15
|
-
|
16
12
|
describe "when initializing" do
|
17
13
|
before do
|
18
|
-
|
19
|
-
expect(Facter).to receive(:value).with('fqdn').and_return("my.server.com")
|
20
|
-
expect(Facter).to receive(:value).with('ipaddress').and_return("my.ip.address")
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should gather data about itself" do
|
24
|
-
Puppet::Resource::Catalog::Compiler.new
|
14
|
+
allow(Puppet).to receive(:version).and_return(1)
|
25
15
|
end
|
26
16
|
|
27
17
|
it "should cache the server metadata and reuse it" do
|
@@ -38,8 +28,6 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
38
28
|
|
39
29
|
describe "when finding catalogs" do
|
40
30
|
before do
|
41
|
-
allow(Facter).to receive(:value).and_return("whatever")
|
42
|
-
|
43
31
|
allow(node).to receive(:merge)
|
44
32
|
allow(Puppet::Node.indirection).to receive(:find).and_return(node)
|
45
33
|
@request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil, :node => node_name)
|
@@ -246,10 +234,10 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
246
234
|
|
247
235
|
describe "when handling a request with facts" do
|
248
236
|
before do
|
249
|
-
Puppet::Node::Facts.indirection.terminus_class = :memory
|
250
237
|
allow(Facter).to receive(:value).and_return("something")
|
251
238
|
|
252
|
-
|
239
|
+
facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386")
|
240
|
+
Puppet::Node::Facts.indirection.save(facts)
|
253
241
|
end
|
254
242
|
|
255
243
|
def a_legacy_request_that_contains(facts, format = :pson)
|
@@ -267,6 +255,8 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
267
255
|
end
|
268
256
|
|
269
257
|
context "when extracting facts from the request" do
|
258
|
+
let(:facts) { Puppet::Node::Facts.new("hostname") }
|
259
|
+
|
270
260
|
it "should do nothing if no facts are provided" do
|
271
261
|
request = Puppet::Indirector::Request.new(:catalog, :find, "hostname", nil)
|
272
262
|
request.options[:facts] = nil
|
@@ -276,21 +266,21 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
276
266
|
|
277
267
|
it "should deserialize the facts without changing the timestamp" do
|
278
268
|
time = Time.now
|
279
|
-
|
280
|
-
request = a_request_that_contains(
|
269
|
+
facts.timestamp = time
|
270
|
+
request = a_request_that_contains(facts)
|
281
271
|
facts = compiler.extract_facts_from_request(request)
|
282
272
|
expect(facts.timestamp).to eq(time)
|
283
273
|
end
|
284
274
|
|
285
275
|
it "accepts PSON facts from older agents" do
|
286
|
-
request = a_legacy_request_that_contains(
|
276
|
+
request = a_legacy_request_that_contains(facts)
|
287
277
|
|
288
278
|
facts = compiler.extract_facts_from_request(request)
|
289
|
-
expect(facts).to eq(
|
279
|
+
expect(facts).to eq(facts)
|
290
280
|
end
|
291
281
|
|
292
282
|
it "rejects YAML facts" do
|
293
|
-
request = a_legacy_request_that_contains(
|
283
|
+
request = a_legacy_request_that_contains(facts, :yaml)
|
294
284
|
|
295
285
|
expect {
|
296
286
|
compiler.extract_facts_from_request(request)
|
@@ -298,7 +288,7 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
298
288
|
end
|
299
289
|
|
300
290
|
it "rejects unknown fact formats" do
|
301
|
-
request = a_request_that_contains(
|
291
|
+
request = a_request_that_contains(facts)
|
302
292
|
request.options[:facts_format] = 'unknown-format'
|
303
293
|
|
304
294
|
expect {
|
@@ -308,15 +298,17 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
308
298
|
end
|
309
299
|
|
310
300
|
context "when saving facts from the request" do
|
301
|
+
let(:facts) { Puppet::Node::Facts.new("hostname") }
|
302
|
+
|
311
303
|
it "should save facts if they were issued by the request" do
|
312
|
-
request = a_request_that_contains(
|
304
|
+
request = a_request_that_contains(facts)
|
313
305
|
|
314
306
|
options = {
|
315
307
|
:environment => request.environment,
|
316
308
|
:transaction_uuid => request.options[:transaction_uuid],
|
317
309
|
}
|
318
310
|
|
319
|
-
expect(Puppet::Node::Facts.indirection).to receive(:save).with(
|
311
|
+
expect(Puppet::Node::Facts.indirection).to receive(:save).with(facts, nil, options)
|
320
312
|
compiler.find(request)
|
321
313
|
end
|
322
314
|
|
@@ -328,7 +320,7 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
328
320
|
:transaction_uuid => request.options[:transaction_uuid],
|
329
321
|
}
|
330
322
|
|
331
|
-
expect(Puppet::Node::Facts.indirection).not_to receive(:save).with(
|
323
|
+
expect(Puppet::Node::Facts.indirection).not_to receive(:save).with(facts, nil, options)
|
332
324
|
compiler.find(request)
|
333
325
|
end
|
334
326
|
end
|
@@ -336,7 +328,6 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
336
328
|
|
337
329
|
describe "when finding nodes" do
|
338
330
|
it "should look node information up via the Node class with the provided key" do
|
339
|
-
allow(Facter).to receive(:value).and_return("whatever")
|
340
331
|
request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil)
|
341
332
|
allow(compiler).to receive(:compile)
|
342
333
|
|
@@ -414,9 +405,37 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
414
405
|
end
|
415
406
|
end
|
416
407
|
|
408
|
+
describe "after finding nodes when checking for a PE version" do
|
409
|
+
include PuppetSpec::Compiler
|
410
|
+
|
411
|
+
let(:pe_version_file) { '/opt/puppetlabs/server/pe_version' }
|
412
|
+
let(:request) { Puppet::Indirector::Request.new(:catalog, :find, node_name, nil) }
|
413
|
+
|
414
|
+
before :each do
|
415
|
+
Puppet[:code] = 'notify { "PE Version: $pe_serverversion": }'
|
416
|
+
end
|
417
|
+
|
418
|
+
it "should not add 'pe_serverversion' when FOSS" do
|
419
|
+
allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
|
420
|
+
catalog = compiler.find(request)
|
421
|
+
|
422
|
+
expect(catalog.resource('notify', 'PE Version: 2019.2.0')).to be_nil
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should add 'pe_serverversion' when PE" do
|
426
|
+
allow(File).to receive(:readable?).with(pe_version_file).and_return(true)
|
427
|
+
allow(File).to receive(:zero?).with(pe_version_file).and_return(false)
|
428
|
+
allow(File).to receive(:read).with(pe_version_file).and_return('2019.2.0')
|
429
|
+
|
430
|
+
allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
|
431
|
+
catalog = compiler.find(request)
|
432
|
+
|
433
|
+
expect(catalog.resource('notify', 'PE Version: 2019.2.0')).to be
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
417
437
|
describe "when filtering resources" do
|
418
438
|
before :each do
|
419
|
-
allow(Facter).to receive(:value)
|
420
439
|
@catalog = double('catalog')
|
421
440
|
allow(@catalog).to receive(:respond_to?).with(:filter).and_return(true)
|
422
441
|
end
|
@@ -47,7 +47,7 @@ describe "Puppet::Resource::Ral" do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should convert ral resources into regular resources" do
|
50
|
-
my_resource = double("my user resource")
|
50
|
+
my_resource = double("my user resource", :title => "my user resource")
|
51
51
|
my_instance = double("my user", :name => "root", :to_resource => my_resource)
|
52
52
|
|
53
53
|
expect(Puppet::Type::User).to receive(:instances).and_return([ my_instance ])
|
@@ -55,7 +55,7 @@ describe "Puppet::Resource::Ral" do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should filter results by name if there's a name in the key" do
|
58
|
-
my_resource = double("my user resource")
|
58
|
+
my_resource = double("my user resource", title: "my user resource")
|
59
59
|
allow(my_resource).to receive(:to_resource).and_return(my_resource)
|
60
60
|
allow(my_resource).to receive(:[]).with(:name).and_return("root")
|
61
61
|
|
@@ -73,11 +73,11 @@ describe "Puppet::Resource::Ral" do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it "should filter results by query parameters" do
|
76
|
-
wrong_resource = double("my user resource")
|
76
|
+
wrong_resource = double("my user resource", title: "my user resource")
|
77
77
|
allow(wrong_resource).to receive(:to_resource).and_return(wrong_resource)
|
78
78
|
allow(wrong_resource).to receive(:[]).with(:name).and_return("root")
|
79
79
|
|
80
|
-
my_resource = double("wrong resource")
|
80
|
+
my_resource = double("wrong resource", title: "wrong resource")
|
81
81
|
allow(my_resource).to receive(:to_resource).and_return(my_resource)
|
82
82
|
allow(my_resource).to receive(:[]).with(:name).and_return("bob")
|
83
83
|
|
@@ -82,7 +82,7 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
|
|
82
82
|
expect(Zlib::GzipReader).to receive(:open).with(sourcefile).and_yield(reader)
|
83
83
|
expect(minitar).to receive(:find_valid_files).with(reader).and_return([name])
|
84
84
|
entry = MockFileStatEntry.new(mode)
|
85
|
-
expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name]).
|
85
|
+
expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name], :fsync => false).
|
86
86
|
and_yield(type, name, {:entry => entry})
|
87
87
|
entry
|
88
88
|
end
|
@@ -38,19 +38,27 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should fail if there is no environment specified" do
|
41
|
-
expect
|
41
|
+
expect {
|
42
|
+
handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {})
|
43
|
+
}.to raise_error(bad_request_error)
|
42
44
|
end
|
43
45
|
|
44
46
|
it "should fail if the environment is not alphanumeric" do
|
45
|
-
expect
|
47
|
+
expect {
|
48
|
+
handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {:environment => "env ness"})
|
49
|
+
}.to raise_error(bad_request_error)
|
46
50
|
end
|
47
51
|
|
48
52
|
it "should fail if the indirection does not match the prefix" do
|
49
|
-
expect
|
53
|
+
expect {
|
54
|
+
handler.uri2indirection("GET", "#{master_url_prefix}/certificate/foo", params)
|
55
|
+
}.to raise_error(bad_request_error)
|
50
56
|
end
|
51
57
|
|
52
58
|
it "should fail if the indirection does not have the correct version" do
|
53
|
-
expect
|
59
|
+
expect {
|
60
|
+
handler.uri2indirection("GET", "#{Puppet::Network::HTTP::CA_URL_PREFIX}/v3/certificate/foo", params)
|
61
|
+
}.to raise_error(bad_request_error)
|
54
62
|
end
|
55
63
|
|
56
64
|
it "should not pass a buck_path parameter through (See Bugs #13553, #13518, #13511)" do
|
@@ -74,7 +82,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
74
82
|
end
|
75
83
|
|
76
84
|
it "should fail if the indirection name is not alphanumeric" do
|
77
|
-
expect
|
85
|
+
expect {
|
86
|
+
handler.uri2indirection("GET", "#{master_url_prefix}/foo ness/bar", params)
|
87
|
+
}.to raise_error(bad_request_error)
|
78
88
|
end
|
79
89
|
|
80
90
|
it "should use the remainder of the URI as the indirection key" do
|
@@ -86,7 +96,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
86
96
|
end
|
87
97
|
|
88
98
|
it "should fail if no indirection key is specified" do
|
89
|
-
expect
|
99
|
+
expect {
|
100
|
+
handler.uri2indirection("GET", "#{master_url_prefix}/node", params)
|
101
|
+
}.to raise_error(bad_request_error)
|
90
102
|
end
|
91
103
|
|
92
104
|
it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
|
@@ -126,7 +138,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
126
138
|
end
|
127
139
|
|
128
140
|
it "should fail if an indirection method cannot be picked" do
|
129
|
-
expect
|
141
|
+
expect {
|
142
|
+
handler.uri2indirection("UPDATE", "#{master_url_prefix}/node/bar", params)
|
143
|
+
}.to raise_error(method_not_allowed_error)
|
130
144
|
end
|
131
145
|
|
132
146
|
it "should not URI unescape the indirection key" do
|
@@ -146,9 +160,11 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
146
160
|
expect(handler).to receive(:check_authorization) do |_, _, arg|
|
147
161
|
expect(arg).not_to include(:environment)
|
148
162
|
end
|
149
|
-
expect
|
150
|
-
|
151
|
-
|
163
|
+
expect {
|
164
|
+
handler.uri2indirection("GET",
|
165
|
+
"#{master_url_prefix}/node/bar",
|
166
|
+
{:environment => 'bogus'})
|
167
|
+
}.to raise_error(not_found_error)
|
152
168
|
end
|
153
169
|
|
154
170
|
it "should not URI unescape the indirection key as passed through to a call to check_authorization" do
|
@@ -327,7 +343,8 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
|
|
327
343
|
|
328
344
|
expect {
|
329
345
|
handler.call(request, response)
|
330
|
-
}.to raise_error(Puppet::Network::HTTP::Error::HTTPNotAcceptableError,
|
346
|
+
}.to raise_error(Puppet::Network::HTTP::Error::HTTPNotAcceptableError,
|
347
|
+
%r{No supported formats are acceptable \(Accept: application/json, text/pson\)})
|
331
348
|
end
|
332
349
|
|
333
350
|
it "should return [] when searching returns an empty array" do
|
@@ -135,7 +135,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
135
135
|
end
|
136
136
|
|
137
137
|
context "when response indicates an overloaded server" do
|
138
|
-
let(:http) { double('http') }
|
138
|
+
let(:http) { double('http', :started? => true) }
|
139
139
|
let(:site) { Puppet::Network::HTTP::Site.new('http', 'my_server', 8140) }
|
140
140
|
let(:verify) { Puppet::SSL::Validator.no_validator }
|
141
141
|
let(:httpunavailable) { Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable') }
|
@@ -158,6 +158,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
158
158
|
|
159
159
|
pool = Puppet.lookup(:http_pool)
|
160
160
|
expect(pool).to receive(:with_connection).with(site, anything).and_yield(http)
|
161
|
+
allow(http).to receive(:finish)
|
161
162
|
|
162
163
|
result = subject.get('/foo')
|
163
164
|
|
@@ -167,6 +168,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
167
168
|
it "should return a 503 response if Retry-After is not convertible to an Integer or RFC 2822 Date" do
|
168
169
|
httpunavailable['Retry-After'] = 'foo'
|
169
170
|
allow(http).to receive(:request).and_return(httpunavailable)
|
171
|
+
allow(http).to receive(:finish)
|
170
172
|
|
171
173
|
pool = Puppet.lookup(:http_pool)
|
172
174
|
expect(pool).to receive(:with_connection).with(site, anything).and_yield(http)
|
@@ -176,9 +178,21 @@ describe Puppet::Network::HTTP::Connection do
|
|
176
178
|
expect(result.code).to eq(503)
|
177
179
|
end
|
178
180
|
|
181
|
+
it "should close the connection before sleeping" do
|
182
|
+
allow(http).to receive(:request).and_return(httpunavailable, httpok)
|
183
|
+
|
184
|
+
pool = Puppet.lookup(:http_pool)
|
185
|
+
expect(pool).to receive(:with_connection).with(site, anything).and_yield(http)
|
186
|
+
|
187
|
+
expect(http).to receive(:finish)
|
188
|
+
|
189
|
+
subject.get('/foo')
|
190
|
+
end
|
191
|
+
|
179
192
|
it "should sleep and retry if Retry-After is an Integer" do
|
180
193
|
httpunavailable['Retry-After'] = '42'
|
181
194
|
allow(http).to receive(:request).and_return(httpunavailable, httpok)
|
195
|
+
allow(http).to receive(:finish)
|
182
196
|
|
183
197
|
pool = Puppet.lookup(:http_pool)
|
184
198
|
expect(pool).to receive(:with_connection).with(site, anything).twice.and_yield(http)
|
@@ -193,6 +207,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
193
207
|
it "should sleep and retry if Retry-After is an RFC 2822 Date" do
|
194
208
|
httpunavailable['Retry-After'] = 'Wed, 13 Apr 2005 15:18:05 GMT'
|
195
209
|
allow(http).to receive(:request).and_return(httpunavailable, httpok)
|
210
|
+
allow(http).to receive(:finish)
|
196
211
|
|
197
212
|
now = DateTime.new(2005, 4, 13, 8, 17, 5, '-07:00')
|
198
213
|
allow(DateTime).to receive(:now).and_return(now)
|
@@ -210,6 +225,7 @@ describe Puppet::Network::HTTP::Connection do
|
|
210
225
|
it "should sleep for no more than the Puppet runinterval" do
|
211
226
|
httpunavailable['Retry-After'] = '60'
|
212
227
|
allow(http).to receive(:request).and_return(httpunavailable, httpok)
|
228
|
+
allow(http).to receive(:finish)
|
213
229
|
Puppet[:runinterval] = 30
|
214
230
|
|
215
231
|
pool = Puppet.lookup(:http_pool)
|
@@ -266,4 +282,30 @@ describe Puppet::Network::HTTP::Connection do
|
|
266
282
|
|
267
283
|
subject.get('/path')
|
268
284
|
end
|
285
|
+
|
286
|
+
describe 'connection request errors' do
|
287
|
+
it "logs and raises generic http errors" do
|
288
|
+
generic_error = Net::HTTPError.new('generic error', double("response"))
|
289
|
+
expect_any_instance_of(Net::HTTP).to receive(:request).and_raise(generic_error)
|
290
|
+
|
291
|
+
expect(Puppet).to receive(:log_exception).with(anything, /^.*failed: generic error$/)
|
292
|
+
expect { subject.get('/foo') }.to raise_error(generic_error)
|
293
|
+
end
|
294
|
+
|
295
|
+
it "logs and raises timeout errors" do
|
296
|
+
timeout_error = Timeout::Error.new
|
297
|
+
expect_any_instance_of(Net::HTTP).to receive(:request).and_raise(timeout_error)
|
298
|
+
|
299
|
+
expect(Puppet).to receive(:log_exception).with(anything, /^.*timed out after .* seconds$/)
|
300
|
+
expect { subject.get('/foo') }.to raise_error(timeout_error)
|
301
|
+
end
|
302
|
+
|
303
|
+
it "logs and raises eof errors" do
|
304
|
+
eof_error = EOFError
|
305
|
+
expect_any_instance_of(Net::HTTP).to receive(:request).and_raise(eof_error)
|
306
|
+
|
307
|
+
expect(Puppet).to receive(:log_exception).with(anything, /^.*interrupted after .* seconds$/)
|
308
|
+
expect { subject.get('/foo') }.to raise_error(eof_error)
|
309
|
+
end
|
310
|
+
end
|
269
311
|
end
|