README.md in puppet-resource_api-1.8.0 vs README.md in puppet-resource_api-1.8.1

- old
+ new

@@ -170,24 +170,133 @@ ### Unit testing The generated unit tests in `spec/unit/puppet/provider/foo_spec.rb` get automatically evaluated with `pdk test unit`. -### `puppet device` support +## Remote resources -To support remote resources using `puppet device`, a few more steps are needed. First a `Puppet::Util::NetworkDevice::<device type>::Device` class needs to exist, which provides facts and connection management . That device class can inherit from `Puppet::Util::NetworkDevice::Simple::Device` to receive a simple default configuration parser using hocon. +Support for remote resources is enabled through a `transport` class. A transport class contains the code for managing connections and processing information to and from the remote resource. For information on how to create a transport class, see the [Resource API specification](https://github.com/puppetlabs/puppet-specifications/tree/master/language/resource-api#transport). -The provider needs to specify the `remote_resource` feature to enable the second part of the machinery. +An example of a transport class: -After this, `puppet device` will be able to use the new provider, and supply it (through the device class) with the URL specified in the [`device.conf`](https://puppet.com/docs/puppet/5.3/config_file_device.html). +```ruby +# lib/puppet/transport/device_type.rb +module Puppet::Transport + # The main connection class to a PAN-OS API endpoint + class DeviceType + def initialize(context, connection_info) + # Initialization eg. validate connection_info + end -#### Device-specific providers + def verify(context) + # Test that transport can talk to the remote target + end -To allow modules to deal with different backends independently of each other, the Resource API also implements a mechanism to use different API providers side-by-side. For a given device type (see above), the Resource API will first try to load a `Puppet::Provider::TypeName::DeviceType` class from `lib/puppet/provider/type_name/device_type.rb`, before falling back to the regular provider at `Puppet::Provider::TypeName::TypeName`. + def facts(context) + # Access target, return a Facter facts hash + end -### Further Reading + def close(context) + # Close connection, free up resources + end + end +end +``` +An example of a corresponding schema: + +```ruby +# lib/puppet/transport/device_type.rb +Puppet::ResourceAPI.register_transport( + name: 'device_type', # points at class Puppet::Transport::DeviceType + desc: 'Connects to a device_type', + # features: [], # future extension points + connection_info: { + host: { + type: 'String', + desc: 'The host to connect to.', + }, + user: { + type: 'String', + desc: 'The user.', + }, + password: { + type: 'String', + sensitive: true, + desc: 'The password to connect.', + }, + enable_password: { + type: 'String', + sensitive: true, + desc: 'The password escalate to enable access.', + }, + port: { + type: 'Integer', + desc: 'The port to connect to.', + }, + }, +) +``` + +### Transport Schema keywords + +Please note that within the transport schema, the following keywords are reserved words: + +#### Usable within the schema + +The following keywords are encouraged within the Transport schema: + +* `uri` - Use when you need to specify a specific URL to connect to. All of the following keys will be computed from the `uri` if possible. In the future more url parts may be computed from the URI as well. +* `host` - Use to specify and IP or address to connect to. +* `protocol` - Use to specify which protocol the transport should use for example `http`, `https`, `ssh` or `tcp` +* `user` - The user the transport should connect as. +* `port` - The port the transport should connect to. + +#### Non-Usable within the schema + +The following keywords are keywords that must not be used by the transport schema: + +* `name` - transports should use `uri` instead of name. +* `path` - reserved as a uri part +* `query` - reserved as a uri part +* `run-on` - This is used by bolt to determine which target to proxy to. Transports should not rely on this key. +* `remote-transport` - This is used to determine which transport to load. It should always be the transport class name "declassified". +* `remote-*` Any key starting with `remote-` is reserved for future use. + +Note: Currently bolt inventory requires that a name be set for every target and always uses that name as the URI. This means there is no way to specify `host` separately from the host section of the `name` when parsed as a URI. + +After the device class, transport class and transport schema have been implemented, `puppet device` will be able to use the new provider, and supply it (through the device class) with the URL specified in the [`device.conf`](https://puppet.com/docs/puppet/5.3/config_file_device.html). + +#### Transport/device specific providers + +To allow modules to deal with different backends independently, the Resource API implements a mechanism to use different API providers side by side. For a given transport/device class (see above), the Resource API will first try to load a `Puppet::Provider::TypeName::<DeviceType>` class from `lib/puppet/provider/type_name/device_type.rb`, before falling back to the regular provider at `Puppet::Provider::TypeName::TypeName`. + +### Puppet backwards compatibility + +To connect to a remote resource through `puppet device`, you must provide a device shim to maintain compatibility with Puppet. The device shim needs to interface the transport to puppet's config and runtime expectations. + +In the simplest case you can use the provided `Puppet::ResourceApi::Transport::Wrapper` like this: + +```ruby +# lib/puppet/util/network_device/device_type/device.rb + +require 'puppet' +require 'puppet/resource_api/transport/wrapper' +# force registering the transport schema +require 'puppet/transport/schema/device_type' + +module Puppet::Util::NetworkDevice::Device_type + class Device < Puppet::ResourceApi::Transport::Wrapper + def initialize(url_or_config, _options = {}) + super('device_type', url_or_config) + end + end +end +``` + +## Further reading + The [Resource API](https://github.com/puppetlabs/puppet-specifications/blob/master/language/resource-api/README.md) describes details of all the capabilities of this gem. The [hue_rsapi module](https://github.com/da-ar/hue_rsapi) is a very simple example for using the Resource API for remote resources. The [meraki module](https://github.com/meraki/puppet-module) is a full example for using the Resource API for remote resources. @@ -229,22 +338,19 @@ Future possibilities: * [Multiple Providers](https://tickets.puppetlabs.com/browse/PDK-530) * [Commands API](https://tickets.puppetlabs.com/browse/PDK-847) -## Development - -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. - -To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). - ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/puppetlabs/puppet-resource_api. ### Cutting a release -To cut a new release, from a current `master` checkout: +In some cases we need to manually cut a release outside of the regular puppet +agent process. + +To do so, follow these instructions from a current `master` checkout: * Start the release branch with `git checkout -b release-prep` * Update `lib/puppet/resource_api/version.rb` to the new version * Update the CHANGELOG * Have a [CHANGELOG_GITHUB_TOKEN](https://github.com/skywinder/github-changelog-generator#github-token) set in your environment