storage_api.extensions package¶
Subpackages¶
Submodules¶
storage_api.extensions.storage module¶
This is a generalised back-end for storage systems.
In general, methods are expected to raise KeyErrors on 404-type errors (e.g. something not found), and ValueErrors on invalid input. In both cases, reasonable descriptions of what went wrong should be included, and – if possible – suggestions on how to fix the situation.
-
class
storage_api.extensions.storage.
DummyStorage
[source]¶ Bases:
storage_api.extensions.storage.StorageBackend
This is a dummy storage back-end meant for testing. It will persist data given to it in RAM and follow the standard API provided by the base class above, but that is about it.
-
policies
¶
-
raise_if_snapshot_absent
(volume_name: str, snapshot_name: str)[source]¶ Raise a KeyError with an appropriate message if a snapshot is absent.
This implies first running raise_if_volume absent(volume_name).
-
raise_if_volume_absent
(volume_name: str)[source]¶ Raise a KeyError with an appropriate message if a volume is absent.
-
volumes
¶
-
-
class
storage_api.extensions.storage.
NetappStorage
(hostname, username, password, vserver, timeout_s=4)[source]¶ Bases:
storage_api.extensions.storage.StorageBackend
A Back-end for a NetApp storage system.
-
create_volume
(volume_name, **fields)[source]¶ Important note: the volume “name” for NetApp is either a name, or a node name and junction path separated by colon. Please note that the node name is ignored, as the user cannot set the node name on creation.
If creating a volume from a junction path, an actual name must be provided as a data field (‘name’) (and vice versa – if creating with a name, junction path must be provided).
-
name_from_path
(junction_path)[source]¶ ‘Resolve’ a junction path to a proper volume name.
Raises KeyError if there was no such volume.
-
node_junction_path
(volume_name)[source]¶ Convert a “volume_name” parameter to a node name and junction path.
Returns: a tuple of (node, junction path). If the string does not adhere to the format, it is assumed to contain only the junction path and the returned node is None.
-
parse_volume_name
(volume_name_or_node_path)[source]¶ Parse a volume name on the format name, or node:junction_path, always returning a unique name.
-
policies
¶
-
volumes
¶ Explicitly ignores volumes belonging to aggr0 and volumes that are restricted.
-
-
class
storage_api.extensions.storage.
StorageBackend
[source]¶ Bases:
object
-
clone_volume
(clone_volume_name, from_volume_name, from_snapshot_name)[source]¶ Create a clone of a volume from a provided snapshot.
Raises: KeyError
– if no such volume or snapshot existsValueError
– if clone_volume_name already exists
-
create_lock
(volume_name, host_owner)[source]¶ Install a lock held by the host host_owner on the given volume.
Raises: ValueError
– if a lock is already held on that volume by another hostKeyError
– if no such volume exists
-
create_policy
(policy_name, rules)[source]¶ Add a new policy with a set of rules to a given volume
Raises: ValueError
– if there is already a policy with that name
-
create_snapshot
(volume_name, snapshot_name)[source]¶ Make a snapshot from the current state of a volume.
Raises: KeyError
– if no volume named volume_name existsValueError
– if there is already a snapshot named snapshot_name, or if the name is invalid.
-
create_volume
(volume_name, **fields)[source]¶ Create a new volume with a given name and the provided data fields.
fields can be at least:
- size_total
Raises: ValueError
– if the data is malformedKeyError
– if the volume already exists
Returns: The created volume.
Back-ends are allowed to add implementation-specific elements.
-
delete_snapshot
(volume_name, snapshot_name)[source]¶ Delete, or the closest possible equivalent, a given snapshot.
Raises: KeyError
– if no such volume or snapshot exists
-
ensure_policy_rule_absent
(policy_name, rule)[source]¶ Idempotently ensure that a given export policy (as represented by an IP with optional mask) is absent in the rules of a given policy. Will delete it if present, otherwise give no warning.
Raises: KeyError
– if no such policy exists.
-
ensure_policy_rule_present
(policy_name, rule)[source]¶ Idempotently ensure that a given export policy (as represented by an IP with optional mask) is present in the rules of a given policy. If it is not present it will be added.
Raises: KeyError
– if no such policy exists.
-
get_policy
(policy_name)[source]¶ Return a (potentially empty) list of export policies in the form of strings representing IP numbers, with possible masks associated with the given policy.
Raises: KeyError
– if volume_name does not exist or does not have a policy named policy_name
-
get_snapshot
(volume_name, snapshot_name)[source]¶ Get the data associated with the snapshot.
Back-ends are allowed to add additional keys.
Raises: KeyError
– if no such volume or snapshot exists
-
get_snapshots
(volume_name)[source]¶ Return a list of snapshots for volume_name.
Raises: KeyError
– if no such volume exists.
-
get_volume
(volume_name)[source]¶ Return (the data for) a specific volume as a dictionary with (at least) the following elements:
- name
- size_used
- size_total
- filer_address
Back-ends are allowed to add implementation-specific elements.
Raises: KeyError
– if no such volume exists
-
init_app
(app: flask.app.Flask, endpoint)[source]¶ Initialise a Flask app context with the storage system.
Parameters: - app (flask.Flask) – The application to install the storage system back-end in
- endpoint (str) – The API endpoint to mount the back-end at.
Example:
app = Flask(__name__) netapp = NetAppStorage() netapp.init_app(app=app, endpoint="netapp")
-
locks
(volume_name)[source]¶ Return the string naming the host currently holding a lock on the volume named volume_name, or None if there were no locks.
Raises: KeyError
– if no such volume exists
-
patch_volume
(volume_name, **data)[source]¶ Update a volume with data from **data.
Raises: ValueError
– on poorly formatted data, or invalid data entries/attempts to write to read-only fieldsKeyError
– if no volume named volume_name exists.
-
policies
()[source]¶ Return a list of export policies for the given back-end, as a list of name/value tuples.
Example:
["my_policy", ["127.0.0.1", "10.10.10.1/24"]]
Notably, no policies would yield []. The interpretation of these values are up to the implementation, but it can be assumed that no policies is not the same thing as a policy with no rules.
Raises: KeyError
– if no such volume exists
-
remove_lock
(volume_name, host_owner)[source]¶ Remove/break/force the lock on a volume, if held by host_owner. Does nothing if no locks were held on volume_name, or if the lock wasn’t held by host_owner.
Raises: KeyError
– if no such volume exists
-
remove_policy
(policy_name)[source]¶ Remove a policy. After removal, it must be possible to create a new policy with the same name.
Raises: KeyError
– if no such volume or policy exists
-
restrict_volume
(volume_name)[source]¶ Restrict or delete a volume. This will cause it to not appear in volumes or get_volume(), as if the volume never existed.
What action is actually performed is platform-dependent, but should be semantically as close to a delete operation as possible.
Notably, there is no guarantee that it is possible to create a new volume with the same name as a recently deleted volume.
-
rollback_volume
(volume_name, restore_snapshot_name)[source]¶ Roll back a volume to a snapshot.
Raises: KeyError
– if volume_name does not exist or does not have a snapshot named restore_snapshot_name.
-
set_policy
(volume_name, policy_name)[source]¶ Set a policy
Raises: KeyError
– if volume_name does not existValueError
– if policy_name does not exist
-
volumes
¶ Return all active and usable volumes of the storage backend as a list of dictionaries (see get_volume() for their format).
Read-only property.
-
-
exception
storage_api.extensions.storage.
ValidationError
[source]¶ Bases:
Exception
An Exception raised when a return value fails to pass its schema validation.
-
storage_api.extensions.storage.
annotate_exception
(exception, annotation)[source]¶ Context manager to annotate a particular type of exception with a descriptive text.
Example: ``` with annotate_exception(KeyError, “no such item!”):
a = foo[‘key’]
-
storage_api.extensions.storage.
normalised_with
(schema_name: str, allow_unknown: bool = False, as_list: bool = False)[source]¶ A decorator to normalise and validate the return values of a function according to a schema.
If as_list is True, validate and normalise each entry in the returned list.
Raises a ValidationError if the schema was not correctly validated.
-
storage_api.extensions.storage.
patch_and_diff
(previous, new)[source]¶ Replace all keys in previous with their values in new, returning a list of keys for which the values changed and the updated previous.