progfiguration.inventory.invstores#

Inventory store

Protocols for inventory stores (host stores and secret stores).

Module Contents#

Classes#

Secret

An abstract class for secrets

HostStore

Hosts, groups, functions, and roles for a site

SecretStore

A protocol for secret storage and encryption.

SecretReference

A reference to a secret by name

Functions#

get_inherited_secret(→ Secret)

Get a secret for a node, inheriting from groups if necessary.

class progfiguration.inventory.invstores.Secret#

Bases: Protocol

An abstract class for secrets

property value: str#

Return the secret value.

This default implementation caches the result in the _cache attribute.

_cache: Any#

An optional cache for the decrypted secret value.

Used by the default implementation of the value property.

secret: str#

The encrypted secret value.

abstract decrypt() str#

Decrypt the secret.

class progfiguration.inventory.invstores.HostStore#

Bases: Protocol

Hosts, groups, functions, and roles for a site

abstract property groups: List[str]#

All groups, in undetermined order

abstract property nodes: List[str]#

All nodes, in undetermined order

abstract property functions: List[str]#

All functions, in undetermined order

abstract property roles: List[str]#

All roles, in undetermined order

abstract property node_groups: Dict[str, List[str]]#

A dict, containing node:grouplist mappings

abstract property function_nodes: Dict[str, List[str]]#

A dict, containing function:nodelist mappings

localhost: progfiguration.localhost.LocalhostLinux#

A localhost object

TODO: can we get rid of this?

node_function: Dict[str, str]#

A dict where keys are node names and values are function names

function_roles: Dict[str, List[str]]#

A dict where keys are function names and value are lists of role names

group_members: Dict[str, List[str]]#

A dict where keys are group names and values are lists of node names

abstract node_rolename_list(nodename: str) List[str]#

A list of all rolenames for a given node

abstract node(name: str) types.ModuleType#

The Python module for a given node

TODO: should return an InventoryNode instead of a ModuleType.

abstract group(name: str) types.ModuleType#

The Python module for a given group

TODO: should return a dict instead of a ModuleType.

abstract role_module(name: str) types.ModuleType#

The Python module for a given role

TODO: should return a ProgfigurationRole subclass instead of a ModuleType.

abstract node_role(secretstore: SecretStore, nodename: str, rolename: str) progfiguration.inventory.roles.ProgfigurationRole#

A dict of {nodename: {rolename: ProgfigurationRole}}

Get an instantiated progfiguration.inventory.roles.ProgfigurationRole object for a given node and role.

We collect all arguments required to instantiate the role, including the superclass arguments like rolepkg and localhost, as well as role-specific arguments accepted by the given ProgfigurationRole subclass and defined as a default argument or in the group or node argument dicts. You can then call .apply() or .calculations() on the role.

Results are cached for subsequent calls.

abstract node_role_list(nodename: str, secretstore: SecretStore) list[progfiguration.inventory.roles.ProgfigurationRole]#

A list of all instantiated roles for a given node

TODO: Deprecate this, it’s just a wrapper around node_role anyway.

class progfiguration.inventory.invstores.SecretStore#

Bases: Protocol

A protocol for secret storage and encryption.

Implementations are encouraged to cache results.

Secrets are stored in three different collections. “node” and “group” collections then use the node/group name. The only name used in the “special” collection is “controller”, for secrets that only the controller should be able to decrypt.

abstract list_secrets(collection: Literal[node, group, special], name: str) List[str]#

List secrets.

abstract get_secret(collection: Literal[node, group, special], name: str, secret_name: str) Secret#

Retrieve a secret from the secret store.

This operation returns an opaque Secret type. The secret does not have to be decrypted yet, but can be, depending on the Secret implementation.

If the secret does not exist, raise a KeyError.

abstract encrypt_secret(hoststore: HostStore, name: str, value: str, nodes: List[str], groups: List[str], controller_key: bool, store: bool = False) str#

Set a secret in the secret store.

This operation encrypts the secret and stores it in the secret store.

If store is True, persist the encrypted value to secret storage. Implementations must make sure that the controller will be able to decrypt. If store is False, the secret is just being displayed to the user or something.

Return the encrypted value. (If we don’t return the encrypted value, it makes no sense to have a store parameter.)

abstract apply_cli_arguments(args: Dict[str, str]) None#

Apply arguments from the command line

Arguments are passed as comma-separated key/value pairs, like --secret-store-arguments key1=value1,key2=value2 and then parsed into a dict.

abstract find_node_key(node: progfiguration.inventory.nodes.InventoryNode)#

If called, this function should find the decryption key for a node.

It may be called by the progfigsite command-line program if the user specifies a node. The implementation may look up the key in the node’s sitedata.

progfiguration.inventory.invstores.get_inherited_secret(hoststore: HostStore, secretstore: SecretStore, node: str, secret_name: str) Secret#

Get a secret for a node, inheriting from groups if necessary.

class progfiguration.inventory.invstores.SecretReference#

Bases: progfiguration.inventory.roles.RoleArgumentReference

A reference to a secret by name

This is a wrapper type that allows us to pass around a reference to a secret without having to know the secret’s value.

name: str#

The name of the secret

dereference(nodename: str, hoststore: HostStore, secretstore: SecretStore) Any#

Get the final value of a role argument for a node.

Arguments to this method:

  • nodename: The name of the node that the argument is being applied to

  • hoststore: The inventory object

This function must retrieve or calculate the final value from its internal data and these arguments.