NAME
Connector::Multi
DESCRIPTION
This class implements a Connector that is capable of dealing with dynamically configured Connector implementations and symlinks.
The underlying concept is that there is a primary (i.e.: boot) configuration source that Multi accesses for get() requests. If the request returns a reference to a SCALAR, Multi interprets this as a symbolic link. The content of the link contains an alias and a target key.
Example
In this example, we will be using a YAML configuration file that is accessed via the connector Connector::Proxy::YAML.
From the programmer's view, the configuration should look something like this:
smartcards:
tokens:
token_1:
status: ACTIVATED
token_2:
status: DEACTIVATED
owners:
joe:
tokenid: token_1
bob:
tokenid: token_2
In the above example, calling get('smartcards.tokens.token_1.status') returns the string 'ACTIVATED'.
To have the data fetched from an LDAP server, we can redirect the 'smartcards.tokens' key to the LDAP connector using '@' to indicate symlinks. Our primary configuration source for both tokens and owners would contain the following entries:
smartcards:
tokens@: connector:connectors.ldap-query-token
owners@: connector:connectors.ldap-query-owners
With the symlink now in the key, Multi must walk down each level itself and handle the symlink. When 'smartcards.tokens' is reached, it reads the contents of the symlink, which is an alias to a connector 'ldap-query-token'. The connector configuration is in the 'connectors' namespace of our primary data source.
connectors:
ldap-query-tokens:
class: Connector::Proxy::Net::LDAP
basedn: ou=smartcards,dc=example,dc=org
uri: ldaps://example.org
bind_dn: uid=user,ou=Directory Users,dc=example,dc=org
password: secret
connectors:
ldap-query-owners:
class: Connector::Proxy::Net::LDAP
basedn: ou=people,dc=example,dc=org
uri: ldaps://example.org
bind_dn: uid=user,ou=Directory Users,dc=example,dc=org
password: secret
*Redirect to env*
Similar to connector you can define a redirect to read a value from the environment.
node1:
key@: env:OPENPKI_KEY_FROM_ENV
calling get('node1.key') will return the value of the environment variable `OPENPKI_KEY_FROM_ENV`.
If the environment variable is not set, undef is returned. Walking over such a node raises a warning but will silently swallow the remaining path components and return the value of the node.
*Inline Redirects*
It is also possible to reference other parts of the configuration using a kind of redirect/symlink.
node1:
node2:
key@: shared.key1
shared:
key1: secret
The '@' sign indicates a symlink similar to the example given above but there is no additional keyword in front of the value and the remainder of the line is treated as an absolute path to read the value from.
If the path value starts with the path separator (default 'dot'), then the path is treated as a relative link and each dot means "one level up".
node1:
node2:
key2@: ..node2a.key
node2a:
key1@: .key
key: secret
SYNOPSIS
The parameter BASECONNECTOR may either be a class instance or the name of the class, in which case the additional arguments (e.g.: LOCATION) are passed to the base connector.
use Connector::Proxy::Config::Versioned;
use Connector::Multi;
my $base = Connector::Proxy::Config::Versioned->new({
LOCATION => $path_to_internal_config_git_repo,
});
my $multi = Connector::Multi->new( {
BASECONNECTOR => $base,
});
my $tok = $multi->get('smartcard.owners.bob.tokenid');
or...
use Connector::Multi;
my $multi = Connector::Multi->new( {
BASECONNECTOR => 'Connector::Proxy::Config::Versioned',
LOCATION => $path_to_internal_config_git_repo,
});
my $tok = $multi->get('smartcard.owners.bob.tokenid');
You can also pass the path as an arrayref, where each element can be a path itself
my $tok = $multi->get( [ 'smartcard.owners', 'bob.tokenid' ]);
OPTIONS
When creating a new instance, the new()
constructor accepts the following options:
- BASECONNECTOR
-
This is a reference to the Connector instance that Connector::Multi uses at the base of all get() requests.
Supported methods
get, get_list, get_size, get_hash, get_keys, set, get_meta Those are routed to the appropriate connector.
get_connector Return the instance of the connector at this node
get_wrapper Return a wrapper around this node. This is like setting a prefix for all subsequent queries.
my $wrapper = $conn->get_wrapper('test.node');
$val = $wrapper->get('foo');
Is the same as $val = $conn->get_wrapper('test.node.foo');