Skip to content

(FM-7829) Update README with transports examples #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 13, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 116 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,128 @@ The `create`/`update`/`delete` methods get called by the `SimpleProvider` base-c

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

def verify(context)
# Test that transport can talk to the remote target
end

def facts(context)
# Access target, return a Facter facts hash
end

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:

#### Device-specific providers
#### Usable within the schema

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`.
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
## 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.

Expand Down