(#14822) Re-evaluate features if they previously were false

Allow features to be re-evaluated each time they are checked, if they
previously evaluated to false.  This allows for providers by features to have
dependencies installed during a run and then for the feature state to change
from false to true.

Caching of feature results that were previously true has been kept.  Caching of
blocks used to evaluate features remains unaffected and are still run only once.
(#14822) Use feature confine for feature tests during run

Fixes two providers to use the "confine :feature" statement, allowing for the
features to be re-evaluated during a run instead of only once.
(#16376) Fix rails compatibility layer for activerecord < 3.0

Previously an alias was attempted between scope and named_scope to allow older
activerecord versions (< 3.0) to work with the inventory service while also
supporting modern activerecord. The scope alias failed because
Puppet::Rails::InventoryNode inherits from ActiveRecord::Base, which has a
scope method already. So activerecord's scope method is found instead of the
intended alias target. This commit removes the alias and simply switches on
activerecord version to use the correct scope (AR >= 3.0) or named_scope (AR <
3.0) method.
(#4680) Reject CA network operations when master CA is disabled

When the master has CA function explicitly disabled, it would still respond to
networked REST requests. They accessed the local certificate store and,
generally, provided quite unexpected results.

For example, if a CSR was submitted it would be accepted successfully and
ignored; no further action, despite the fact that the master would never do
anything with it, and it could not be acted on.

Now, instead, we explicitly fail for remote requests.  This delivers a clear,
unambiguous error message to the agent and stops them functioning - a much
better outcome overall.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Merge pull request #1156 from daniel-pittman/bug/2.7.x/4680-better-handling-of-csr-submission-problems

(#4680) Reject CA network operations when master CA is disabled
(#2888) Add settings catalog info to README_DEVELOPER

Without this patch the README_DEVELOPER doesn't mention the special
settings catalog which I overlooked while working on #2888.  If the
settings catalog was in mind while I worked on this issue I probably
would have solved it a lot faster than it took to track down.

In particular, wrapping the File.open method was an effective way to
quickly track down the codepath that was improperly writing and
truncating the lockfile.
(#2888) Fix race condition with puppetdlockfile

Without this patch applied there is a race condition where by two or
more concurrent puppet agent processes will eventually result in a
deadlock state where all processes consider catalog runs to be
administratively disabled.

This is a problem because the configuration catalog stops being applied
periodically.  The system will not recover unless there is manual
intervention by the end user.

The problem is caused by the settings catalog.  The settings catalog
will contain a file resource for the puppetdlockfile if the file exists.
When two processes are running, the file will exist when it is created
by the other process.  When the file resource is in the settings
catalog, it will be created as a zero length file, or truncated to a
zero length file if it already exists.

Here is the state transition for two puppet agent --test processes, A
and B.

    A:
    lock()
      File.exist? => false
      File.open()
      catalog.run
      ...

    B:
    Puppet::Util::Settings#to_catalog
      File.exist? => true
      catalog.add_resource(Puppet::Type::File)
      ...
      resource synchronizes
      Puppet::Type::File#write(:content)

    A:
    unlock()
      unlink()

    B:
    settings catalog apply
      File.open("puppetdlock", "wb") { ... } # Truncates the file!

    A:
    locked? => true
    mine? => false

    B:
    locked? => true
    mine? => false

    A and B are deadlocked.

This patch fixes the problem by marking the puppetdlockfile settings as
a `:type => :setting`.  This change prevents the settings catalog from
containing a file resource for the puppetdlockfile setting.

Paired-with: Josh Cooper <josh@puppetlabs.com>
Merge remote-tracking branch 'upstream/2.7.x' into 3.x

* upstream/2.7.x:
  (#4680) Reject CA network operations when master CA is disabled

Conflicts:
	lib/puppet/indirector/request.rb
	spec/unit/indirector/request_spec.rb
Merge remote-tracking branch 'upstream/3.x'

* upstream/3.x:
  (#4680) Reject CA network operations when master CA is disabled
Merge branch 'bug/2.7.x/2888_fix_puppetdlock_deadlock' into 2.7.x

* bug/2.7.x/2888_fix_puppetdlock_deadlock:
  (#2888) Fix race condition with puppetdlockfile
  (#2888) Add settings catalog info to README_DEVELOPER
Implement a JSON file terminus to mirror YAML.

For a bunch of local caching and retrieval, Puppet uses a YAML backed local
file terminus to store, retrieve, and search content.  This is great, but the
YAML encoder is super-slow and painfully odd across Ruby versions.

Our PSON support is much more reliable, as well as substantially faster, and
is pretty much as capable.  There isn't much reason, other than migration
cost, to prefer YAML to PSON encoding of data transfer documents.

Having a JSON terminus allows the user to configure, manually, the use of JSON
everywhere that we previously used YAML.  While this doesn't bring the
benefits out of the box, it allows users to select this while we flush out any
lingering bugs left in the support code and system.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Add catalog JSON terminus to improve performance.

This adds a JSON backed catalog terminus, so that the catalog cache can
migrate away from YAML to a faster and more stable storage format.

This is not the default: that still falls to old, trustable YAML which we know
to be stable and effective.

To enable this, edit your routes.yaml file and add:

    agent:
      catalog:
        cache: json

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Merge branch '2.7.x' into 3.x

* 2.7.x:
  (#2888) Fix race condition with puppetdlockfile
  (#2888) Add settings catalog info to README_DEVELOPER

Conflicts:
	lib/puppet/defaults.rb
	spec/integration/defaults_spec.rb
Merge branch '3.x'

* 3.x:
  (#2888) Fix race condition with puppetdlockfile
  (#2888) Add settings catalog info to README_DEVELOPER
Implement Symbol#intern when it is missing.

In order to reduce use of `Puppet::Util#symbolize` in the code - which is
called some 90,000 times in a real-world run - being able to intern a symbol
is convenient.

This is a simple implementation: it just returns itself.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Use `intern` rather than `symbolize` it Puppet::Type

The cost of symbolize is ~ 50 percent higher than the cost of intern, when
applied to either a string or a symbol.  Given this is called some 90,000
times in my real world test run, that adds up to a non-zero amount of
wasted time.

Sadly, this only works out at 0.15 seconds real time reduction, but it is
better than nothing - and takes out 85,000 extra calls.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
zaml: statically determine the to_ascii8bit implementation.

Instead of asking every single string the same question, "do you respond to
`encoding`", we can just figure that out once and choose an implementation
based on the result - since it is a static test on the same class every time.

This saves ~ 0.1 second of runtime, which is small but cheap.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
zaml: unify on a single definition of `to_zaml` for Symbol

There were two competitive definitions of the `to_zaml` function over Symbol,
one in monkey_patches and one in the core ZAML library.

The monkey patch version won in practice, so now they are unified, and the
monkey patch version is adopted to replace the core ZAML version, in the zaml
Ruby file.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(Maint) Remove fragile test

This test began to fail with

  1) Puppet::SSL::Key should default to the :file terminus
       Failure/Error: @class.indirection.terminus_class.should == :file
         expected: :file
              got: :disabled_ca (using ==)
         Diff:
         @@ -1,2 +1,2 @@
         -:file
         +:disabled_ca
       # ./spec/unit/ssl/key_spec.rb:20

which was caused by other tests setting the terminus_class for the
Puppet::SSL::Key class. Since this is testing no interesting logic and
just looking at a default (that can be changed and not recovered), I'm
just removing the test.
Merge remote-tracking branch 'upstream/2.7.x' into 3.x

* upstream/2.7.x:
  (Maint) Remove fragile test