Resource implementation: the provider
To make changes, a resource requires an implementation, or provider. It is the code used to retrieve, update and delete the resources of a certain type.
The two fundamental operations to manage resources are reading and writing
system state. These operations are implemented as get and set. The implementation itself is a Ruby class in the Puppet::Provider namespace, named after the type using
CamelCase.
puppet/provider/<type_name>/<type_name>.rb. The class
also has the CamelCased type name twice.At runtime, the current and intended system states a specific resource. These are represented as Ruby hashes of the resource's attributes and applicable operational parameters:
class Puppet::Provider::AptKey::AptKey
def get(context)
[
{
name: 'name',
ensure: 'present',
created: '2017-01-01',
# ...
},
# ...
]
end
def set(context, changes)
changes.each do |name, change|
is = change.has_key? :is ? change[:is] : get_single(name)
should = change[:should]
# ...
end
end
end
The get method reports the current
state of the managed resources. It returns an enumerable of all existing resources. Each
resource is a hash with attribute names as keys, and their respective values as values. It is
an error to return values not matching the type specified in the resource type. If a requested
resource is not listed in the result, it is considered to not exist on the system. If
the get method
raises an exception, the provider is marked as unavailable during the current run, and all
resources of this type fails in the current transaction. The exception message is
reported.
The set method updates resources to a new state. The changes parameter gets passed a hash of
change requests, keyed by the resource's name. Each value is another hash with the optional
:is and :should keys. At least one of the two must be
specified. The values are of the same shape as those returned by get. After the set, all resources are in the state defined by
the :should values.
A missing :should entry indicates that a resource will be removed from the system. Even
a type implementing the ensure
=> [present, absent] attribute pattern must react correctly on a
missing :should entry. An :is key might contain the last available system state from a
prior get call. If
the :is value
is nil, the resources
were not found by get. If
there is no :is key,
the runtime did not have a cached state available.
The set method should always return nil. Signaling progress through the logging utilities described
below. If the set method throws an exception, all resources that should change in this call
and haven't already been marked with a definite state, are marked as failed. The runtime only
calls the set method
if there are changes to be made, especially when resources are marked with noop => true (either locally
or through a global flag). The runtime does not pass them to set. See supports_noop for changing this
behavior if required.
Both methods take a context parameter which provides utilties from the runtime environment, and is described in more detail there.
Implementing simple providers
In many cases, the resource type follows the conventional patterns of Puppet, and does not gain from the complexities around
batch-processing changes. For those cases, the SimpleProvider class supplies a proven foundation that reduces the amount
of code necessary to get going.
SimpleProvider requires that your type follows these
common conventions:
-
nameis the name of yournamevarattribute. -
ensureattribute is present and has theEnum[absent, present]type.
To start using SimpleProvider, inherit from the class
like this:
require 'puppet/resource_api/simple_provider' # Implementation for the wordarray type using the Resource API. class Puppet::Provider::AptKey::AptKey < Puppet::ResourceApi::SimpleProvider # ...
Next, instead of the set method, the provider needs to implement the create, update or delete methods:
-
create(context, name, should): Called to create a resource.-
context: provides utilities from the runtime environment. -
name: the name of the new resource. -
should: a hash of the attributes for the new instance.
-
-
update(context, name, should): Called to update a resource.-
context: provides utilties from the runtime environment. -
name: the name of the resource to change. -
should: a hash of the desired state of the attributes.
-
-
delete(context, name): Called to delete a resource.-
context: provides utilities from the runtime environment. -
name: the name of the resource that to be deleted.
-
The SimpleProvider does basic logging and error
handling.
In this section: